最最最通俗易懂的promise手寫系列(一)

先看一下這一次要講的涉及到的promise的基礎用法php

let pms = new Promise((resolve, reject) => {
    setTimeout(() => {
        if (parseInt(Math.random()*10) > 5) {
             console.log('隨機數大於5,算任務成功了')
             resolve('還能夠傳參哦')
        } else {
            console.log('隨機數< 5,算任務失敗了')
            reject('還能夠傳參哦< 5')
        }
    }, 1500)
  })

  pms.then((value) => {
    console.log('success', value)
  }, (reason) => {
    console.log('fail', reason)
  })

1.5s後若是隨機的數大於5走resolve()輸出:
'隨機數大於5,算任務成功了', 'success',
小於5走reject(),輸出:
'隨機數< 5,算任務失敗了', 'fail'. 數組

咱們先寫promise的這兩個功能:
構造函數的參數接受一個函數。
函數在被調用的時候,會被promise傳入兩個參數resolve跟reject。promise

function Promise(executor){
    executor(resolve, reject)
    function resolve(){}
    function reject(){}
  }

能夠看到一new Promise就會執行傳入的函數,也就是咱們起名爲executor的函數.
你們確定納悶兒爲啥要在executor裏調用resolve或者reject,咱們裏先上代碼:dom

function Promise(executor) {
    let self = this;
    self.value = undefined;
    self.reason = undefined;
    self.status = 'pending';

    self.onFulFilledCallbacks = [];
    self.onRejectedCallbacks = [];

    function resolve(value) {
        if (self.status === 'pending') {
            self.value = value;
            self.status = 'resolved'

            self.onFulFilledCallbacks.forEach(onFulFilled => {
                onFulFilled(self.value)
            });
        }
    }
    function reject(reason) {
        if (self.status === 'pending') {
            self.reason = reason;
            self.status = 'rejected';
            self.onRejectedCallbacks.forEach(onRejected => {
                onRejected(self.reason)
            });
        }
    }

    try {
        executor(resolve, reject);
    } catch (error) {
        reject(error)
    }
}

Promise.prototype.then = function (onFulFilled, onRejected) {
    if (this.status === 'pending') {
        this.onFulFilledCallbacks.push(() => {
            onFulFilled(this.value)
        }); 
        this.onRejectedCallbacks.push(() => {
            onRejected(this.reason)
        })
    } else if (this.status === 'resolved') {
        onFulFilled(this.value);
    } else if (this.status === 'rejected') {
        onRejected(this.reason);
    }
}

promise的三種狀:等待pending,成功resolve,失敗rejected.(說直接一點就是用來記錄resolve或者reject是否已經調用,也就是常說的那個executor任務執行成功了仍是失敗了)函數

這一次咱們新增了兩個數組onFulFilledCallbacks、onRejectedCallbacks用來保存調用then的時候傳的兩個回調函數(固然若是在調用then的時候已經resolve或reject,那就直接執行傳入的函數,不用保存了),因此executor裏必定會調用resolve或者reject中的一個,由於一個函數的執行不是this

(邏輯上成功)

就是prototype

(邏輯上失敗)

.對應咱們寫的例子就是隨機數不是大於5就是小於5. code

executor任務成功了確定有成功後的結果,失敗了咱們確定也拿到失敗的緣由。因此value與reason一個是用來保存成功的結果,一個是用來保存失敗的緣由。blog

ps:onFulFilledCallbacks、onRejectedCallbacks定爲數組的緣由是爲了這個功能:get

pms.then((value) => {
    console.log('success1', value)
  }, (reason) => {
    console.log('fail1', reason)
  })
pms.then((value) => {
    console.log('success2', value)
  }, (reason) => {
    console.log('fail2', reason)
  })
//then屢次得把這些函數給存起來,到時候成功或者失敗的時候,遍歷依次執行~

下一張咱們進入Promise最迷人的鏈式調用.
最最最通俗易懂的promise手寫系列(二)- 鏈式調用
轉載於猿2048:➝《最最最通俗易懂的promise手寫系列(一)》

相關文章
相關標籤/搜索