搜索

首页  >  问答  >  正文

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 天前869

全部回复(3)我来回复

  • 伊谢尔伦

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

    Promise 就是为了解决异步流程控的而生的,其使用核心就是then方法;
    then初看起来是很像回调,但then的特质是可以处理异常及链式写法.
    打个比方,几个ajax请求依赖如下:

    A1 -> A2;
    Aa -> Ab;
    Ab + Ac -> 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
  • 取消回复