手寫Promise中then方法返回的結果或者規律

明月人倚樓發表於2021-05-23

1. Promise中then()方法返回來的結果或者規律

我們知道 promise 的 then 方法返回來的結果值[result]是由:

它指定的回撥函式的結果決定的

2.比如說下面這一段程式碼

let p = new Promise((resolve, reject) => {
    resolve('ok');
})

const result= p.then(res => {
    alert(res)
}, err => {
    console.log(err)
})

也就是說result的結果值:是下面這一段程式碼決定的
也就是回撥函式返回來的結果決定的
res => {
    alert(res);//此時它返回來的是非Promise型別。
}

如果說:它返回的的是非Promise型別的資料,如undefined; 數字,字串。
那麼 result就是一個成功的Promise;
如果你沒有返回來,result值應該為undefined;
如果你返回來值了,那麼result的值就是你返回來的值

如果說:它返回來的是一個Promise,
你返回來的promise就決定了then方法返回來的Promise的結果和狀態;

如果大家覺得這個有一點不好理解;看這個圖

3.用程式碼說明

 <script>
        let p = new Promise((resolve, reject) => {
            resolve('ok');
        })
        const result = p.then(res => {
            // 這裡返回出去的是一個非Promise型別;
            // 根據上面的內容,result是一個成功的Promise,它的結果就是你返回去的值;
            // 這裡由於你什麼都沒有返回,所以是一個undefined
            console.log('res', res)
        }, err => {
            console.log(err)
        })
        console.log('result', result)
    </script>

4 我們現在定義返回來的結果

<script src="./Promise.js"></script>
<script>
    let p = new Promise((resolve, reject) => {
        resolve('ok');
    })
    const result = p.then(res => {
        console.log('res', res) //輸出 res ok
    }, err => {
        console.log(err)
    })
    console.log('result', result)//輸出 result undefined
</script>

為什麼我們的手寫的promise返回來的僅僅只有undefined;
沒有狀態,因為我們現在手寫的promise什麼都沒有返回來哈

5.我們現在封裝的程式碼

6 先處理回撥函式返回的是一個非promise
新增返回的是一個Promise物件
return new Promise((resolve,reject)=>{ })

// 獲取回撥函式的執行結果
let chenggong= onResolve(this.PromiseValue);

然後返回對應的結果

接受返回來的
<script src="./Promise.js"></script>
<script>
    let p = new Promise((resolve, reject) => {
        resolve('ok');
    })
    const result = p.then(res => {
       // 這裡我們的程式碼返回出去的是一個非Promise型別;
       // 根據上面的內容,result是一個成功的Promise,它的結果就是你返回去的值;
       // 這裡由於你什麼都沒有返回,所以是一個undefined
        console.log('res', res)

        //return 'ok'
    }, err => {
        console.log(err)
    })
    console.log('result', result)
</script>
function Promise(executor) {
  const self = this;
  function resolve(data) {
    // 如果狀態發生改變就直接返回(為了讓Promise的狀態只發生一次改變);
    if (self.PromiseStatus !== "pending") return;
    self.PromiseStatus = "resolved";
    self.PromiseValue = data;

    // 呼叫成功的回撥函式進行遍歷
    self.callBack.forEach((item) => {
      item.onResolve(data);
    });
  }
  // 同樣宣告成為一個函式;修改狀態
  function reject(err) {
    // 如果狀態發生改變就直接返回(為了讓Promise的狀態只發生一次改變);
    if (self.PromiseStatus !== "pending") return;
    self.PromiseStatus = "rejected";
    self.PromiseValue = err;
    // 呼叫失敗的回撥函式數進行遍歷
    self.callBack.forEach((item) => {
      item.onReject(err);
    });
  }
  this.PromiseStatus = "pending";
  this.PromiseValue = null;
  // 宣告屬性 new  add
  this.callBack = [];
  // 對異常進行處理;使用try catch
  try {
    executor(resolve, reject);
  } catch (err) {
    reject(err);
  }
}
// 自定義封裝then方法執行回撥
Promise.prototype.then = function (onResolve, onReject) {
    // 返回一個promise物件
    return new Promise((resolve,reject)=>{
        if (this.PromiseStatus === "resolved") {
            // 獲取回撥函式的執行結果
          let chenggong= onResolve(this.PromiseValue);

          if(chenggong instanceof Promise){
              //
          }else{
            // 不是Promise型別的物件
            // 結果的物件狀態【成功】
            resolve(chenggong)
          }

        }
        if (this.PromiseStatus === "rejected") {
            onReject(this.PromiseValue);
        }
        // 如果是pending的狀態
        if (this.PromiseStatus === "pending") {
            // 這個是儲存回撥函式
            this.callBack.push({
            onResolve: onResolve,
            onReject: onReject,
            });
        }
    })
  
};

返回的值是undefined

返回的值是ok

7.處理回撥函式返回的是一個promise型別的

 <script src="./Promise.js"></script>
    <script>
        let p = new Promise((resolve, reject) => {
            resolve('ok');
        })
        const result = p.then(res => {
            // 返回的是一個非promise型別的;由於什麼都沒有返回,它的結果值應該是一個undefined
            // console.log('res', res)

            // 返回的是一個非promise型別的;返回的應該是一個ok
            // return 'ok'

            // 返回的是一個Promise型別的,
            // 你返回來的promise就決定了then方法返回來的Priose的結果和狀態
            // 此時我們返回的是成功狀態,結果是(我是成功的)
            return new Promise((resolve, reject) => {
                resolve('我是成功的');
            })
        }, err => {
            console.log(err)
        })
        console.log('result', result)
    </script>
function Promise(executor) {
  const self = this;
  function resolve(data) {
    // 如果狀態發生改變就直接返回(為了讓Promise的狀態只發生一次改變);
    if (self.PromiseStatus !== "pending") return;
    self.PromiseStatus = "resolved";
    self.PromiseValue = data;

    // 呼叫成功的回撥函式進行遍歷
    self.callBack.forEach((item) => {
      item.onResolve(data);
    });
  }
  // 同樣宣告成為一個函式;修改狀態
  function reject(err) {
    // 如果狀態發生改變就直接返回(為了讓Promise的狀態只發生一次改變);
    if (self.PromiseStatus !== "pending") return;
    self.PromiseStatus = "rejected";
    self.PromiseValue = err;
    // 呼叫失敗的回撥函式數進行遍歷
    self.callBack.forEach((item) => {
      item.onReject(err);
    });
  }
  this.PromiseStatus = "pending";
  this.PromiseValue = null;
  // 宣告屬性 new  add
  this.callBack = [];
  // 對異常進行處理;使用try catch
  try {
    executor(resolve, reject);
  } catch (err) {
    reject(err);
  }
}
// 自定義封裝then方法執行回撥
Promise.prototype.then = function (onResolve, onReject) {
    // 返回一個promise物件
    return new Promise((resolve,reject)=>{
        if (this.PromiseStatus === "resolved") {
            // 獲取回撥函式的執行結果
          let chenggong= onResolve(this.PromiseValue);

          if(chenggong instanceof Promise){
            // 如果你是一個Promise,那麼可以去呼叫這個then方法
            chenggong.then(v=>{
                resolve(v);
            },r=>{
                reject(r);
            })
          }else{
            // 不是Promise型別的物件
            // 結果的物件狀態【成功】
            resolve(chenggong)
          }

        }
        if (this.PromiseStatus === "rejected") {
            onReject(this.PromiseValue);
        }
        // 如果是pending的狀態
        if (this.PromiseStatus === "pending") {
            // 這個是儲存回撥函式
            this.callBack.push({
            onResolve: onResolve,
            onReject: onReject,
            });
        }
    })
};

補充的圖片,便於理解

8丟擲異常處理

   <script src="./Promise.js"></script>
    <script>
        let p = new Promise((resolve, reject) => {
            resolve('ok');
        })
        const result = p.then(res => {
            // 返回的是一個非promise型別的;由於什麼都沒有返回,它的結果值應該是一個undefined
            // console.log('res', res)

            // 返回的是一個非promise型別的;返回的應該是一個ok
            // return 'ok'

            // 返回的是一個Promise型別的,
            // 你返回來的promise就決定了then方法返回來的Priose的結果和狀態
            // 此時我們返回的是成功狀態,結果是(我是成功的)
            // return new Promise((resolve, reject) => {
            //     resolve('我是成功的');
            // })

            // 丟擲異常
            throw 'err info'
        }, err => {
            console.log(err)
        })
        console.log('result', result)
    </script>
function Promise(executor) {
  const self = this;
  function resolve(data) {
    // 如果狀態發生改變就直接返回(為了讓Promise的狀態只發生一次改變);
    if (self.PromiseStatus !== "pending") return;
    self.PromiseStatus = "resolved";
    self.PromiseValue = data;

    // 呼叫成功的回撥函式進行遍歷
    self.callBack.forEach((item) => {
      item.onResolve(data);
    });
  }
  // 同樣宣告成為一個函式;修改狀態
  function reject(err) {
    // 如果狀態發生改變就直接返回(為了讓Promise的狀態只發生一次改變);
    if (self.PromiseStatus !== "pending") return;
    self.PromiseStatus = "rejected";
    self.PromiseValue = err;
    // 呼叫失敗的回撥函式數進行遍歷
    self.callBack.forEach((item) => {
      item.onReject(err);
    });
  }
  this.PromiseStatus = "pending";
  this.PromiseValue = null;
  // 宣告屬性 new  add
  this.callBack = [];
  // 對異常進行處理;使用try catch
  try {
    executor(resolve, reject);
  } catch (err) {
    reject(err);
  }
}
// 自定義封裝then方法執行回撥
Promise.prototype.then = function (onResolve, onReject) {
    // 返回一個promise物件
    return new Promise((resolve,reject)=>{
        if (this.PromiseStatus === "resolved") {
            try{
                let chenggong= onResolve(this.PromiseValue);
                if(chenggong instanceof Promise){
                    // 如果你是一個Promise,那麼可以去呼叫這個then方法
                    chenggong.then(v=>{
                        resolve(v);
                    },r=>{
                        reject(r);
                    })
                }else{
                    // 不是Promise型別的物件
                    // 結果的物件狀態【成功】
                    resolve(chenggong)
                }
            }catch(e){
                reject(e);
            }
            // 獲取回撥函式的執行結果
        }
        if (this.PromiseStatus === "rejected") {
            onReject(this.PromiseValue);
        }
        // 如果是pending的狀態
        if (this.PromiseStatus === "pending") {
            // 這個是儲存回撥函式
            this.callBack.push({
            onResolve: onResolve,
            onReject: onReject,
            });
        }
    })
};

相關文章