Promise原理及源碼解釋

有不對的,可以指出來,我這裏只是想記一下筆記,方便我以後看。


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
   <script>
    let st = setTimeout;
    const FULL_FILLED = 'fullFilled'; // 成功
    const REJECTED = 'rejected'; // 失敗
    const PENDING = 'pending';//這裏用的setTimeout做異步操作,所以在執行異步之前的時間裏,狀態都是pending
    let count = 0;
    let Promise = function (fn) {//fn就是promise中的函數參數,這個參數有兩個內部定義好的resolve和reject函數參數
        this.id = count++;
        this.status = PENDING;
        this.successCallbacks = [];//用來保存then裏邊的成功回調函數
        this.failedCallbacks = [];//用來保存then裏邊失敗的回調函數
        let resolve = (v)=> {//promise的resolve執行,後會執行then中的成功回調函數,這個v參數,會傳過去
            setTimeout(()=>{
                // resolve(value);
                this.value = v;
                this.status = FULL_FILLED;//如果成功會從pending狀態變成fullFilled
                this.successCallbacks.forEach( fn => fn(this.value) )
            })
        }
        let reject = (v) => {
            setTimeout(()=>{
                // reject(value);
                this.value = v;
                this.status = REJECTED;//失敗的話從pending狀態變成rejected狀態
                this.failedCallbacks.forEach( fn => fn(this.value) )
            })
        }
        try {
            fn(resolve,reject)
        } catch (e) {
            reject(e); // new Promise().then 執行失敗
        }
    }
    function excutePromise (promiseOrVal,resolve,reject) {//這是第一個參數,是判斷then中的返回是一個【promise】還是【普通的基本類型值】
        if (promiseOrVal instanceof Promise) {
            // 還沒有寫 (then  從promise中取值)
            promiseOrVal.then((v)=>{
                excutePromise(v,resolve,reject);//這個就是一直遞歸判斷then中返回的是不是promise還是基本值的函數
            });
        } else {
            // value 基本數據類型
            resolve(promiseOrVal);  // then中如果返回的是【基本類型的值】執行resolve函數,就直接進行到下一個的.then的回調函數裏面,否則的話就是promise,繼續進行循環遞歸去判斷返回的是promise還是基本類型值
        }
    }

    // then 一定是要返回Promise供外部.then
    Promise.prototype.then = function (onFullFilledFn,onRejectedFn) {
        let chainPromise;//這個結果就是then的返回值,一定要是promise,供外部的.then
        // 如果當前,3秒以內,狀態是【Pending】
        if (this.status === PENDING) {//如果是pending狀態,就說明,也不知道要走成功還是失敗,所以有兩種可能
          chainPromise = new Promise((resolve,reject)=>{
                  // 是pending狀態,先把成功或者是失敗的回調函數保存起來,等待狀態改變後,直接調用,這個目的就是保存函數
            this.successCallbacks.push(()=>{
               try {
                  setTimeout(()=>{
                        // resovle後纔會被髮布,所執行
                    let value = onFullFilledFn(this.value);
                    // value有可能是Promise, 也有可能是一般的值
                    excutePromise(value,resolve,reject);//這個函數就是去判斷返回的值是否是promise還是基本值,基本值的話,就會執行resolve,想定與放行開關,進入到下一個then中
                  })
               }catch(e) {
                   reject(e);
               }
            });
            this.failedCallbacks.push(()=>{
                try {
                   setTimeout(()=>{
                        // reject後纔會被髮布,所執行
                        let value = onRejectedFn(this.value);
                        // value有可能是Promise, 也有可能是一般的值
                        excutePromise(value,resolve,reject);
                   })
               }catch(e) {
                   reject(e);
               }
            })
          });
        } 

        if (this.status === FULL_FILLED) {//如果狀態是成功,直接走成功回調
            chainPromise = new Promise((resolve,reject) => {
                try {
                   setTimeout(()=>{
                    let value = onFullFilledFn(this.value);
                    excutePromise(value,resolve,reject);
                   })
                } catch (e) {
                    reject(e);
                }
            });
        }

        if (this.status === REJECTED) {//如果狀態是失敗
            chainPromise = new Promise((resolve,reject) => {
                try {
                    let value = onRejectedFn(this.value);
                    excutePromise(value,resolve,reject);
                } catch (e) {
                    reject(e);
                }
            });
        }
        return chainPromise;
    }
    





    // 模擬3組異步
    // 返回的是Promise實例
    new Promise(function (resolve,reject) {
        console.log('promise執行了');//1
        st(()=>{
            console.log('第1件事。。。');//2
            resolve('abcd');
        },3000);
    })
    .then( (data)=> {
        return new Promise((resovle,reject)=>{
            st(()=>{
                console.log('第2件事');//3
                resovle('xxx');//這個執行了,纔會執行下一個then,它就是一個開關作用,這個參數會作爲下一個then的實參,
            },3000);
        });
    })
    .then((d)=>{
        console.log('結束了',d);//4,d的值:【d:'xxx'】
    })


   </script>


</body>
</html>

.then一定是一個promise,供外部(後續)的.then才能執行,
.then 是立刻執行的,沒辦法控制它停止,每個then裏的回調函數,有可能是一個promise
或者一個普通的基本類型的值,如果是promise,只有resolve,纔會執行下一個then裏的
回調函數,否則直接往下執行;(有一個遞歸就是判斷then裏的回調函數是不是一個promise,如果是
就繼續遞歸)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章