搜尋

首頁  >  問答  >  主體

javascript - 關於 Promise 非同步操作的疑惑,以及如果更優雅的編寫

#
function Promise(fn) {
  var state = 'pending';
  var value;
  var deferred = null;

  function resolve(newValue) {
    if(newValue && typeof newValue.then === 'function') {
      newValue.then(resolve, reject);
      return;
    }
    state = 'resolved';
    value = newValue;

    if(deferred) {
      handle(deferred);
    }
  }

  function reject(reason) {
    state = 'rejected';
    value = reason;

    if(deferred) {
      handle(deferred);
    }
  }

  function handle(handler) {
    if(state === 'pending') {
      deferred = handler;
      return;
    }

    var handlerCallback;

    if(state === 'resolved') {
      handlerCallback = handler.onResolved;
    } else {
      handlerCallback = handler.onRejected;
    }

    if(!handlerCallback) {
      if(state === 'resolved') {
        handler.resolve(value);
      } else {
        handler.reject(value);
      }

      return;
    }

    var ret = handlerCallback(value);
    handler.resolve(ret);
  }

  this.then = function(onResolved, onRejected) {
    return new Promise(function(resolve, reject) {
      handle({
        onResolved: onResolved,
        onRejected: onRejected,
        resolve: resolve,
        reject: reject
      });
    });
  };

  fn(resolve, reject);
}
大家讲道理大家讲道理2705 天前867

全部回覆(3)我來回復

  • 伊谢尔伦

    伊谢尔伦2017-07-05 11:06:56

    Promise 是為了解決非同步流程控的而生的,其使用核心就是then方法;
    then初看起來是很像回調,但then的特質是可以處理異常及鍊式寫法.
    打個比方,幾個ajax請求依賴如下:

    A1 -> A2;
    Aa -> Ab;
    Ab + Ac -> Ad;
    A2 + Ad -> Ax;

    -> Ad;

    A2 + Ad -> Ax;

    如果用Promise,程式碼會很清晰

    首先準備好A1,A2,Aa,Ab,Ac,Ad,Ax 都是根據依賴反回promise對像的函數,我就不寫了
    然後可以看Promise表演了:

    Promise.all([
        A1().then(A2),      //A1 -> A2
        Promise.all([
            Aa().then(Ab),  //Aa -> Ab
            Ac()            //Ac
        ]).then(Ad)         //Ab + Ac -> Ad;
    ]).then(Ax,Err)         //A2 + Ad -> Ax
    .then(function(v){
    //完成
    })

    A1,Aa和Ac沒有依賴,會並發執行,之後會根據依賴完成的情況來繼續,

    不論哪一個Ajax出問題,都會觸發最後的Err事來統一處理錯誤;

    如果你用回調來寫一下試試,要嘛效率不好,要嘛回呼方法裡加一堆程式碼來判斷依賴的情況.

    參考碼:🎜
    //首先准备好 A1,A2,Aa,Ab,Ac,Ad,Ax 都是基于回调的异步函数
    var a2,ab,ac,ad;  //用来保存完成情况的变量
    function runAx(){
        if(a2 == undefined || ad == undefined) return; //判断依赖
        Ax(a2,ad,function(e,v){
            //完成
        })
    }
    function runAd(){
        if(ab == undefined || ac == undefined) return; //判断依赖
        Ad(ab,ac,function(e,v){
            ad = v;
            runAx();
        })
    }
    A1(function(e,v){   
        A2(v,function(e,v){
            a2 = v;
            runAx();
        })
    })
    Aa(function(e,v){
        Ab(v,function(e,v){
            ab = v;
            runAd();
        })
    })
    Ac(function(e,v){
        ac = v;
        runAd();
    })
    🎜上面的程式碼沒有去處理error,就這麼長了,如果依賴再複雜一點,可以想像代碼量,而且容易寫錯;🎜

    回覆
    0
  • 为情所困

    为情所困2017-07-05 11:06:56

    你的理解基本上對,實際上Promise沒簡化多少,只是減少了嵌套的層級。

    所以,終極解決方案就是Async/Await,題主可以去查查看資料。

    回覆
    0
  • 怪我咯

    怪我咯2017-07-05 11:06:56

    優雅就是一個then接著一個then,把回調聖誕樹造型擼直,這就是Promises的貢獻。

    我寫程式要七、八個回呼嵌套,Promises爽的一比。

    你覺得then寫法都嫌麻煩,那就不要用咯,用Async/Await

    回覆
    0
  • 取消回覆