AngularJS 如何做到动态创建多个 promise 后, 以队列同步的方式依次执行? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
97world
V2EX    程序员

AngularJS 如何做到动态创建多个 promise 后, 以队列同步的方式依次执行?

  •  
  •   97world 2016-03-11 23:03:29 +08:00 6668 次点击
    这是一个创建于 3506 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如果是两个相互依赖的 promise 可以用嵌套的方式来执行, 例如下面这样:

    var promise1 = GetPromise(1); promise1.then(function (result1) { var para1 = result1.para; var promise2 = GetPromise(para1); promise2.then(function (result2) { console.log(result2); }, function (msg) { // Handle error }); }, function (msg) { // Handle error }); 

    但是如果有多个 promise 的话, 上面的做法就不能满足了, 是否有其他方式可以做到?

    18 条回复    2016-03-15 22:10:12 +08:00
    Arrowing
        1
    Arrowing  
       2016-03-11 23:13:36 +08:00
    既然没了依赖,就不需要再嵌套了。
    可以用组合 promise 。
    $q.all(promises).then(function(){}, function(){});
    chairuosen
        2
    chairuosen  
       2016-03-11 23:43:53 +08:00 via iPhone
    lz 意思是否为, n 个上下依赖的 promise 的顺序执行?
    var list,current;
    current = list.shift()();
    For item in list
    current = current.then(item)
    sox
        3
    sox  
       2016-03-11 23:56:15 +08:00
    PromiseA()
    .then(PromiseB)
    .then(PromiseC)
    huanglexus
        4
    huanglexus  
       2016-03-12 00:02:02 +08:00
    楼主貌似你没有理解 promise, 你这样写出来的 promise 和 callback hell 有什么区别?
    leofml
        5
    leofml  
       2016-03-12 0044:25 +08:00
    ```Javascript
    var promise1 = GetPromise(1);

    promise1.then(function (result1) {
    var para1 = result1.para;
    var promise2 = GetPromise(para1);
    return promise2;
    }).then(function (result2) {
    console.log(result2);
    }).catch(function (msg) {
    // Handle error
    });
    ```
    wind4
        6
    wind4  
       2016-03-12 12:40:35 +08:00
    then()可以接受一个 Promise ,然后串行执行 Promise 。
    wind4
        7
    wind4  
       2016-03-12 12:55:08 +08:00
    给一段代码,你感受一下

    function action1() {
    return new Promise(function(resolve, reject) {
    // 同步任务的演示
    if (Math.random() < 0.5) {
    return reject();
    }

    return resolve();
    });
    }

    function action2() {
    return new Promise(function(resolve, reject) {
    // 异步任务的演示
    superagent
    .get('http://www.baidu.com')
    .end(function(err, response) {
    if (err) {
    // 传递错误信息给 catch(function(err) { ... })
    return reject(err);
    }

    // 将请求信息传递给 then(function(response){ ... })
    return resolve(response);
    });
    });
    }

    Promise.resolve()
    .then(action1);
    .then(action2);
    .then(function(response) {
    // response 就是 action2 的 response
    })
    .catch(function(err) {
    // 如果是 action1 触发的 catch, err 为空
    // 如果是 action2 触发的 catch, err 等于 action2 的 err
    });

    Promise.all([
    action1,
    action2,
    ])
    .then(function(results) {
    // 获取结果
    // results[0]
    // results[1]
    })
    .catch()
    97world
        8
    97world  
    OP
       2016-03-12 18:46:34 +08:00
    @chairuosen 你是明白我的需求了..但好像我对 Promise 理解得不太透彻, 竟然看不太懂你这段代码..让我折腾一下
    chairuosen
        9
    chairuosen  
       2016-03-12 19:09:18 +08:00
    @97world list = [
    function(){
    return new Promise(...)
    },function........
    ];
    拼一个 list[0]().then(list[1]).then(list[2]).....
    zhuangzhuang1988
        10
    zhuangzhuang1988  
       2016-03-12 19:27:22 +08:00
    hantsy
        11
    hantsy  
       2016-03-12 20:16:34 +08:00
    $q.all
    97world
        12
    97world  
    OP
       2016-03-12 20:34:05 +08:00
    @chairuosen 我试了一下你说的方法, 但是有点奇怪, 每个 promise 里有一个请求, 遍历完 list, 所有的请求是一起发出的, 不是等第一个 promise 请求完毕后, 再发出第二 promise 的请求..
    chairuosen
        13
    chairuosen  
       2016-03-12 20:56:24 +08:00
    @97world 每个 function 必须是 return 一个 Promise http://fex.baidu.com/blog/2015/07/we-have-a-problem-with-promises/
    jinwyp
        14
    jinwyp  
       2016-03-12 23:48:40 +08:00
    看来 promise 楼上的很多人都没真正理解, q.all 只能解决同步 promise, 但没有解决顺序问题,如果需求是要顺序执行的 all 是不行的



    两种方法, 一种循环 然后 p = p.then()

    另一种用 array 的 reduce 就是 promises.reduce((a, b) => a.then(b))

    原来如此。被 reduce.length 麻痹了[good] //@王见充: reduce 似乎可以传 initialValue : promises.reduce((a, b) => a.then(b), Promise.resolve())//@勾三股四: reduce 确实更合适,不过这样写的话第一个项目必须是 Promise 对象… //@王见充: promises.reduce((a, b) => a.then(b))

    http://weibo.com/1712131295/DfAgvDjhc?type=repost#_rnd1457797661134

    promise 里面的细节其实还是很多的
    duhastmich
        15
    duhastmich  
       2016-03-13 15:49:35 +08:00
    Promise 创建完成就会执行了,要顺序执行肯定不能先把 Promise 创建出来,先创建一组函数,每个函数返回一个 Promise 是个办法。还以换个思路,把一个值” pipe ”到一组函数里,就像 shell 那样 https://github.com/zweifisch/promised-util/blob/c05aa70eda3a2f7735f9d86a24e7bba3a225ef62/index.js#L63-L70
    97world
        16
    97world  
    OP
       2016-03-15 22:02:32 +08:00
    @jinwyp 啊终于有人了解我的意图并指出楼上的错误了..
    97world
        17
    97world  
    OP
       2016-03-15 22:03:51 +08:00
    @duhastmich 看来我对 Promise 的了解还很不透彻, 如果不是你说 Promise 创建完就会执行, 我根本连 Promise 的执行顺序都不清楚..
    97world
        18
    97world  
    OP
       2016-03-15 22:10:12 +08:00
    @jinwyp @duhastmich 非常感谢两位! 我现在的做法就是递归+callback, 尽管这种做法并不优雅, 但总算是解决问题了, 两位提供的方案都给我了很大的启发, 我会根据两位提供的方法去重构一下这部分的代码. 再次感谢.
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1137 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 23:34 PVG 07:34 LAX 16:34 JFK 19:34
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86