簡樸完成 ES6 Promise

完成的一個簡樸的ES6 Promise(假如有毛病的處所,願望人人能夠不吝賜教)

僅完成Promise及.then要領

最下方有完整代碼

最先

一個
promise對象吸收的是一個
callback

這個
callback吸收兩個參數
(resolve,reject)

當我們在
callback內實行
resolve
reject的時刻,就會挪用
Promise內定義的
resolve
reject函數

然後,
resolve
reject函數會轉變Promise的狀況

所以它應該是像下面如許的

function MyPromise(callback) {
  // 保留this值
  var self = this
  // 紀錄狀況null為pending,true為resolved,false為reject
  var state = null
  // 紀錄resolve的參數
  var param = null

  // 實行傳入的callback並轉變promise對象狀況
  callback(resolve, reject)
  // resolve要領
  function resolve(data) {
    // 轉變狀況
    state = true
    param = data
  }

  // reject要領
  function reject(err) {
    state = false
    param = err
  }
}

但沒有
then要領的
Promise對象是不完整的(完整沒有用)

所以我們須要一個
then要領,要記着
then要領返回的也是一個
promise對象

then要領吸收兩個可選的參數
(onFulfilled, onRejected)(我們能夠先疏忽可選兩個字)

then要領傳進來的參數必需是函數,假如不是就要疏忽(PromiseA+範例)(我們能夠也先疏忽這句話)

  this.then = function (onFulfilled, onRejected) {
    // 返回一個新的promise對象
    return new self.constructor(function (resolve, reject) {
      // then
    })
  }

接下來就是
then要領的詳細完成了

then要領中
onFulfilled, onRejected的返回值會作為新promise的實行效果

onFulfilled, onRejected這兩個函數要在promise的狀況變成pending或resolved的時刻才離別實行
所以假如promise要領狀況為resolvedrejected的話,我們就能夠直接在then要領中實行resolve(onFulfilled(param))reject(onRejected(param))

  this.then = function (onFulfilled, onRejected) {
    // 返回一個新的promise對象
    return new self.constructor(function (resolve, reject) {
       if (state === true) {
        // param是promise對象完成后的效果
        resolve(onFulfilled(param))
      } else if (state === false) {
        reject(onRejected(param))
      } else {
        // 沒有實行終了,怎麼辦
      }
    })
  }

但假如
promise的狀況為
pending

因為原始
promise的狀況我們是沒法動態獵取的,因而我們就須要在他實行狀況轉變的時刻同時實行
onFulfilled
onRejected要領

我們能夠把這個要領放在原始
promise對象的
resolve
reject要領中實行

因而我們要在
promise的對象定義中增加四個參數,離別紀錄
onFulfilled
onRejected,以及
then要領返回的新
promise對象的
resolve
reject

然後假如實行
then要領的時刻
promise對象的狀況為
pending的話,就將上述四個參數紀錄起來

// then要領返回的promise對象的resolve和reject
var nextResolve = null
var nextReject = null
// 紀錄then要領的參數,onFulfilled和onRejected
var asynconFulfilled = null
var asynconRejected = null

//then要領
this.then = function (onFulfilled, onRejected) {
    // 返回一個新的promise對象
    return new self.constructor(function (resolve, reject) {
      if (state === true) {
        // param是promise對象完成后的效果
        resolve(onFulfilled(param))
      } else if (state === false) {
        reject(onRejected(param))
      } else {
        nextResolve = resolve
        nextReject = reject
        asynconFulfilled = onFulfilled
        asynconRejected = onRejected
      }
    })
  }

接下來就是原始
promise中的
resolve
reject的從新完成

 // resolve要領
  function resolve(data) {
    // 轉變狀況
    state = true
    param = data
    nextResolve(asynconFulfilled(param))
  }

  // reject要領
  function reject(err) {
    state = false
    param = err
    nextReject(asynconRejected(param))
  }

很簡樸不是嗎

我們繼承

上述完成我們一向沒有斟酌一個很主要的狀況,假如
then要領返回的照樣一個
promise對象,那末假如我們後邊另有
then要領的話就要守候前一個
then要領中的
promise對象的狀況從
pending變成完成

這要怎麼做呢

什麼時刻能夠以為then要領返回的
promise對象實行終了了呢,這裏我們就要用到
then要領(@_@,邊寫邊用…),


resolve要領為例

var self = this
// resolve要領
function resolve(data) {
  // 紀錄onFulfilled的實行效果
  let parmise
  // 轉變狀況
  state = true
  param = data
  // 實行紀錄的onFulfilled
  parmise = asynconFulfilled(param)
  if(parmise === undefined){
    // 假如parmise為undefined,就不能剖析parmise.constructor
  } else if (parmise.constructor === self.constructor) {
    // 守候通報進來的promise對象實行終了,然後依據通報進來的promise對象的狀況實行resolve或reject
    // 注重,這個param是形參,在then要領的promise中實行
    promise.then(function (param) {
      resolve(param)
    }, function (param) {
      reject(param)
    })
  } else {
    // 這個是前邊的then返回的不是promise對象的狀況
    resolve(promise)
  }
}

前面我們疏忽了兩點 (
then要領吸收兩個可選的參數(onFulfilled, onRejected)) 和 (
then要領傳進來的參數必需是函數,假如不是就要疏忽)

var self = this
// resolve要領
function resolve(data) {
  // 紀錄onFulfilled的實行效果
  var parmise
  // 轉變狀況
  state = true
  param = data
  // 實行紀錄的onFulfilled
  // begin--------------
  if (typeof onFulfilled === 'function') {
    promise = onFulfilled(param)
    if (promise === undefined) {
      // 待補充
    } else if (promise.constructor === self.constructor) {
      // 注重,這個param是形參,在then要領的promise中實行
      promise.then(function (param) {
        resolve(param)
      }, function (param) {
        reject(param)
      })
    } else {
      reject(promise)
    }
  } else {
    // 假如onFulfilled不是function,疏忽,直接resolve或reject
    resolve(param)
  }
  // ---------------end
}

上面begin到end之間的代碼還要在
then要領挪用,所以我們能夠把這段代碼籠統為一個函數

resolve
reject的道理雷同,只需注重
假如不是function 的話須要實行reject

onFulfilled和 
onRejected只要在[實行環境]客棧僅包括
平台代碼時才可被挪用

所以將上述
begin-end之間的代碼放到
seTimeout中實行(瀏覽器環境)

function resolve(data) {
  // 紀錄onFulfilled的實行效果
  var parmise
  // 轉變狀況
  state = true
  param = data
  // 實行紀錄的onFulfilled
  window.setTimeout(function () {
    // begin--------------
    // 上述代碼
    // ---------------end
  }, 0)
}

下面是完整代碼

注:沒有完成準確的事宜輪迴

// 簡樸完成ES6 Promise
function MyPromise(callback) {
  // 保留this值
  var self = this
  // 紀錄狀況null為pending,true為resolved,false為reject
  var state = null
  // 紀錄resolve的參數
  var param = null
  // then要領返回的promise對象的resolve和reject
  var nextResolve = null
  var nextReject = null
  // 紀錄then要領的參數,onFulfilled和onRejected
  var asynconFulfilled = null
  var asynconRejected = null

  // 實行並轉變promise對象狀況
  callback(resolve, reject)
  // then要領
  this.then = function (onFulfilled, onRejected) {
    // 返回一個新的promise對象
    return new self.constructor(function (resolve, reject) {
      // 推斷異步代碼是不是實行終了(是不是resolve或reject)
      // 若實行終了就在then要領中馬上實行,否則將四個參數紀錄下來,守候state停當后再實行doAsyn*函數
      if (state === true) {
        doAsynconFulfilled(onFulfilled, resolve, reject)
      } else if (state === false) {
        doAsynconRejected(onRejected, resolve, reject)
      } else {
        nextResolve = resolve
        nextReject = reject
        asynconFulfilled = onFulfilled
        asynconRejected = onRejected
      }
    })
  }
  // resolve要領
  function resolve(data) {
    // 轉變狀況
    state = true
    param = data
    if(nextResolve){
        doAsynconFulfilled(asynconFulfilled, nextResolve, nextReject)
    }
  }

  // reject要領
  function reject(err) {
    state = false
    param = err
    if(nextReject){
        doAsynconRejected(asynconRejected, nextResolve, nextReject)
    }
  }

  // 中心要領(我以為是)

  function doAsynconFulfilled(onFulfilled, resolve, reject) {
      window.setTimeout(function () {
        // 推斷onFulfilled是不是為function,不是則疏忽
        if (typeof onFulfilled === 'function') {
          // 實行onFulfilled要領獵取返回值promise()
          let promise = onFulfilled(param)
          // 假如promise為undefined 實行 if
          // 假如promise為MyPromise對象 實行 else if
          // 假如promise為非MyPromise對象 實行 else
          if (promise === undefined) {
            resolve(param)
            // 待補充
          } else if (promise.constructor === self.constructor) {
            // 守候通報進來的promise對象實行終了,然後依據通報進來的promise對象的狀況實行resolve或reject
            promise.then(function (param) {
              resolve(param)
            }, function (param) {
              reject(param)
            })
          } else {
            // 實行then要領返回的對象的resolve
            resolve(promise)
          }
        } else {
          // 通報參數
          resolve(param)
        }
      }, 0)
    
  }

  function doAsynconRejected(onRejected, resolve, reject) {
    window.setTimeout(function () {
        if (typeof onRejected === 'function') {
          let promise = onRejected(param)
          if (promise === undefined) {
            reject(param)
            // 待補充
          } else if (promise.constructor === self.constructor) {
            promise.then(function (param) {
              resolve(param)
            }, function (param) {
              reject(param)
            })
          } else {
            reject(promise)
          }
        } else {
          // 通報毛病信息
          reject(param)
        }
    }, 0)
  }
}
// 測試運用
var b = function (message) {
    return new MyPromise(function (resolve, reject) {
        document.body.onclick = function () {
            resolve('click:' + message)
        }
    })
}
var a = new MyPromise(function (resolve, reject) {
  resolve(123)
}).then(function (message) {
    return b(message)
}).then().then(function (message) {
    console.log('final:' + message)
},function (err) {
    console.log('final:' + err)
})
console.log('window')

固然另有Promise.all等要領。

終了!

    原文作者:bello
    原文地址: https://segmentfault.com/a/1190000015076915
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞