1. 程式人生 > >Promise的實現機制(一)

Promise的實現機制(一)

  開發過程非同步請求很常見,但是回撥地獄我們還是可以去避免的,這篇文章就不再贅述Promise的具體使用方法,而是探尋一下它的實現機制。首先是一個簡單的Promise的例子:

function getInfo(){
  return new Promise(function(reslve,reject){
    http.get(url,function(result){
     reslove(reslut.id)
   })
  })
}

getInfo().then(function(id){...})

  開始的時候最大的疑惑是:.then()的操作怎麼就知道我的非同步請求成功了?其實內部的原理就是在一個promise的例項裡面的then方法註冊我所有非同步請求成功後的回撥,而後通過reslove方法將非同步請求結果返回,也就是將之前註冊的非同步回撥一一執行,大概的實現程式碼就是:

function Promise(fn){
  var value = null
  var callbacks = [] //非同步回撥的陣列

  this.then(function(callbackDone){
    callbacks.push(callbackDone) // 將所有的非同步回撥放入陣列
    return this //支援鏈式呼叫
  })

  function reslove(value){
    callbacks.forEach(function(callback){
      callback(value) // 遍歷執行非同步回撥
    })
  }

  fn(reslove)
}

  描述起來就是我們在new Promise()的時候,傳入的函式執行非同步請求,將非同步請求的回撥通過呼叫.then()方法將回調註冊入callbacks裡,非同步請求成功之後執行reslove(result)的方法,將非同步回撥全部執行。這就是一個Promise最基礎版本的實現,那目前的問題就是不能讓reslove的方法先於then方法執行,那我們能想到最簡單的方法就是加入定時器的延時處理:

function Promise(fn){
  var value = null
  var callbacks = [] //非同步回撥的陣列

  this.then(function(callbackDone)
{
callbacks.push(callbackDone) // 將所有的非同步回撥放入陣列 return this //支援鏈式呼叫 }) setTimeout(function(){ // 延時處理 function reslove(value){ callbacks.forEach(function(callback){ callback(value) // 遍歷執行非同步回撥 }) } },0) fn(reslove)

  而接下來就是考慮狀態機制的問題了,我們都知道Promise的三個狀態:pending,fulfilled,rejected。而且只能是由pending變為fulfilled或rejected且狀態不可逆,也就是狀態一旦改變就不會再次改變了,那我們將程式碼稍微改動下:

function Promise(fn){
  var value = null
  var callbacks = [] //非同步回撥的陣列
  var status = 'pending'

  this.then(function(callbackDone){
    if(status === 'pending'){
      callbacks.push(callbackDone) // 將所有的非同步回撥放入陣列
    }
    callbackDone(value)
    return this //支援鏈式呼叫
  })

  setTimeout(function(){
  // 延時處理
    function reslove(newValue){
      var value = newValue
      status = 'fulfilled'
      callbacks.forEach(function(callback){
        callback(value) // 遍歷執行非同步回撥
      })
    }
  },0)

  fn(reslove)

  其實以上就是Promise實現的核心程式碼,後續還會涉及到異常處理和鏈式Promise,我也需要更進一步的學習,不過目前也是已經瞭解到Promise內部實現的機制是怎樣的,也很有助於我平常使用的時候更好的理解它。那後期會再更一版Promise的實現機制(二),對於異常處理和鏈式Promise再進行一些探討