實現一個超簡單的Promise

一 Promise函數

Promise函數是es6中一個比較有用的特性,通常用來處理異步操做。讓你的代碼中再也不只有回調函數套回調函數。
promise函數的運行流程以下圖:es6

圖片描述

來看下面一個簡單demo,數組

setTimeout(function(){
 console.log('hello')
},1000)

下面再看下promise的實現promise

let p1 = new Promise(function(resolve) {
   setTimeout(function(){
    resolve('hello')
},1000)
})
.then(function(resolve){
   console.log(resolve)
})

上面兩種實現的話,咱們能夠看出,當使用promise的時候,其更能凸顯出執行代碼和處理結果的邏輯分離異步

二 簡單模擬一個promise

function MyPromise (fn) {
  this._status = 'pending'
  this._value = undefined
  this._onResolvedCallback = []
  this._onRejectCallback = []
  fn(resolve.bind(this), reject.bind(this))
}
function resolve (value) {
  if (this._status === 'pending') {
    this._status = 'resolved'
    this._value = value
    var fn
    while (fn = this._onResolvedCallback.pop()) {
      fn.call(this, value)
    }
  }
}
function reject (reason) {
  if(this._status === 'pending') {
    this._status = 'reject'
    this._value = reason
    var fn
    while (fn = this._onRejectCallback.pop()) {
      fn.call(this,reason)
    }
  }
}
MyPromise.prototype.then = function (onResolved, onRejected) {
  var self = this
  var promise2
  onResolved = typeof onResolved === 'function' ? onResolved : function (v) {}
  onRejected = typeof onRejected === 'function' ? onRejected : function (r) {}
  if (self._status === 'resolved') {
    return promise2 = new MyPromise (function (resolve, reject) {
      try {
        var x = onResolved(self._value)
        if (x instanceof MyPromise) {
          x.then(resolve,reject)
        }
        resolve(x)
      } catch (e) {
        reject(e)
      }
    })
  }
  if (self._status === 'rejected') {
    return promise2 = new MyPromise (function (resolve, reject) {
      try {
        var x = onRejected(self._value)
        if (x instanceof MyPromise) {
          x.then(resolve,reject)
        }
      } catch(e) {
        reject(e)
      }
    })
  }
  if (self._status === 'pending') {
    return promise2 = new MyPromise (function (resolve, reject) {
      self._onResolvedCallback.push(function (value) {
        try{
          var x = onResolved(self._value)
          if (x instanceof MyPromise) {
              x.then(resolve, reject)
          }
        } catch (e) {
          reject(e)
        }
      })
      self._onRejectCallback.push(function(reason) {
        try {
          var x =onRejected(self._value)
          if(x instanceof Promise) {
            x.then(resolve, reject)
          }
          resolve(x)
        } catch (e) {
          reject(e)
        }
      })
    })
  }
}
//test code
  var myFirstPromise = new MyPromise(function(resolve, reject){
      setTimeout(function(){
          resolve("成功!"); //代碼正常執行!
      }, 1000);
  });
  myFirstPromise.then(function (successMessage) {
     console.log("Yay! " + successMessage);
  })

上述是一個模擬promise基礎功能的代碼。主要分爲三塊,構造函數,resolve和reject函數,以及then函數
下面來簡單說明一下這三個部分函數

2.1 構造函數

function MyPromise (fn) {
  this._status = 'pending'
  this._value = undefined
  this._onResolvedCallback = []
  this._onRejectCallback = []
  fn(resolve.bind(this), reject.bind(this))
}

構造函數部分,主要爲promise對象聲明瞭一個狀態屬性,一個值屬性(傳遞resolve或者reject的值)還有當promise的狀態爲resolve或者reject時候的回調函數。this

2.2 resolve部分和reject部分

function resolve (value) {
  if (this._status === 'pending') {
    this._status = 'resolved'
    this._value = value
    var fn
    while (fn = this._onResolvedCallback.pop()) {
      fn.call(this, value)
    }
  }
}
function reject (reason) {
  if(this._status === 'pending') {
    this._status = 'reject'
    this._value = reason
    var fn
    while (fn = this._onRejectCallback.pop()) {
      fn.call(this,reason)
    }
  }
}

resolve和reject函數,主要用來改變狀態,用傳遞的值運行回調函數,spa

2.3 then部分

MyPromise.prototype.then = function (onResolved, onRejected) {
  var self = this
  var promise2
  onResolved = typeof onResolved === 'function' ? onResolved : function (v) {}
  onRejected = typeof onRejected === 'function' ? onRejected : function (r) {}
  if (self._status === 'resolved') {
    return promise2 = new MyPromise (function (resolve, reject) {
      try {
        var x = onResolved(self._value)
        if (x instanceof MyPromise) {
          x.then(resolve,reject)
        }
        resolve(x)
      } catch (e) {
        reject(e)
      }
    })
  }
  if (self._status === 'rejected') {
    return promise2 = new MyPromise (function (resolve, reject) {
      try {
        var x = onRejected(self._value)
        if (x instanceof MyPromise) {
          x.then(resolve,reject)
        }
      } catch(e) {
        reject(e)
      }
    })
  }
  if (self._status === 'pending') {
    return promise2 = new MyPromise (function (resolve, reject) {
      self._onResolvedCallback.push(function (value) {
        try{
          var x = onResolved(self._value)
          if (x instanceof MyPromise) {
              x.then(resolve, reject)
          }
        } catch (e) {
          reject(e)
        }
      })
      self._onRejectCallback.push(function(reason) {
        try {
          var x =onRejected(self._value)
          if(x instanceof Promise) {
            x.then(resolve, reject)
          }
          resolve(x)
        } catch (e) {
          reject(e)
        }
      })
    })
  }
}

then方法返回的是一個promise對象,通常是返回新的promise。then方法的邏輯主要是判斷status的狀態,改變狀態,把處理方法添加到promise的方法屬性數組裏面。prototype

三 總結

圖片描述VPepbcode

相關文章
相關標籤/搜索