登录  /  注册
javascript - 关于 Promise 异步操作的疑惑,以及如果更优雅的编写
大家讲道理
大家讲道理 2017-07-05 11:04:56
[JavaScript讨论组]
  • 这几天看了翻了很多关于 「promise」相关技术贴,看的是眼花缭,一知半解大概了解其作用。

  • 先说说问题吧,项目中用到最多少就是Ajax,有个很不爽的问题「多条ajax依赖请求」假设: R1 > R2( r1_result ) > R3( r2_result ),
    最省事的做法全部都同步了吧,结果就是体验很糟糕,页面一度假死,loading 也不转了,使用异步操令人恶心的就是一层套一层的回调,以及后续更多的依赖操作。

  • 生命在于折腾,于是就回到了第一段中各种翻阅,看到某位兄台对 promise 原理刨析,下面引用这位兄台中的code,http://malcolmyu.github.io/ma...

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);
}
  • 看完我不禁又疑惑了, then( function(){ do... } ),这丫还不是个回调嘛,难道是折腾的意义就是套个语法糖(我不信)。

  • 存在即合理,所以最后怎样合理使用 promise, 如何更优雅操作ajax流程?顺便提下有使用 ( axios \ fetch.js )感觉如何?

大家讲道理
大家讲道理

光阴似箭催人老,日月如移越少年。

全部回复(3)
伊谢尔伦

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,就这么长了,如果依赖再复杂一点,可以想象代码量,而且容易写错;

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2024 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号