AngularJS 如何做到动态创建多个 promise 后, 以队列同步的方式依次执行? - V2EX
请不要在回答技术问题时复制粘贴 AI 生成的内容
97world

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

  •  
  •   97world Mar 11, 2016 7047 views
    This topic created in 3714 days ago, the information mentioned may be changed or developed.

    如果是两个相互依赖的 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 replies    2016-03-15 22:10:12 +08:00
    Arrowing
        1
    Arrowing  
       Mar 11, 2016
    既然没了依赖,就不需要再嵌套了。
    可以用组合 promise 。
    $q.all(promises).then(function(){}, function(){});
    chairuosen
        2
    chairuosen  
       Mar 11, 2016 via iPhone
    lz 意思是否为, n 个上下依赖的 promise 的顺序执行?
    var list,current;
    current = list.shift()();
    For item in list
    current = current.then(item)
    sox
        3
    sox  
       Mar 11, 2016
    PromiseA()
    .then(PromiseB)
    .then(PromiseC)
    huanglexus
        4
    huanglexus  
       Mar 12, 2016
    楼主貌似你没有理解 promise, 你这样写出来的 promise 和 callback hell 有什么区别?
    leofml
        5
    leofml  
       Mar 12, 2016
    ```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  
       Mar 12, 2016
    then()可以接受一个 Promise ,然后串行执行 Promise 。
    wind4
        7
    wind4  
       Mar 12, 2016
    给一段代码,你感受一下

    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
       Mar 12, 2016
    @chairuosen 你是明白我的需求了..但好像我对 Promise 理解得不太透彻, 竟然看不太懂你这段代码..让我折腾一下
    chairuosen
        9
    chairuosen  
       Mar 12, 2016
    @97world list = [
    function(){
    return new Promise(...)
    },function........
    ];
    拼一个 list[0]().then(list[1]).then(list[2]).....
    zhuangzhuang1988
        10
    zhuangzhuang1988  
       Mar 12, 2016
    hantsy
        11
    hantsy  
       Mar 12, 2016
    $q.all
    97world
        12
    97world  
    OP
       Mar 12, 2016
    @chairuosen 我试了一下你说的方法, 但是有点奇怪, 每个 promise 里有一个请求, 遍历完 list, 所有的请求是一起发出的, 不是等第一个 promise 请求完毕后, 再发出第二 promise 的请求..
    chairuosen
        13
    chairuosen  
       Mar 12, 2016
    @97world 每个 function 必须是 return 一个 Promise http://fex.baidu.com/blog/2015/07/we-have-a-problem-with-promises/
    jinwyp
        14
    jinwyp  
       Mar 12, 2016
    看来 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  
       Mar 13, 2016
    Promise 创建完成就会执行了,要顺序执行肯定不能先把 Promise 创建出来,先创建一组函数,每个函数返回一个 Promise 是个办法。还以换个思路,把一个值” pipe ”到一组函数里,就像 shell 那样 https://github.com/zweifisch/promised-util/blob/c05aa70eda3a2f7735f9d86a24e7bba3a225ef62/index.js#L63-L70
    97world
        16
    97world  
    OP
       Mar 15, 2016
    @jinwyp 啊终于有人了解我的意图并指出楼上的错误了..
    97world
        17
    97world  
    OP
       Mar 15, 2016
    @duhastmich 看来我对 Promise 的了解还很不透彻, 如果不是你说 Promise 创建完就会执行, 我根本连 Promise 的执行顺序都不清楚..
    97world
        18
    97world  
    OP
       Mar 15, 2016
    @jinwyp @duhastmich 非常感谢两位! 我现在的做法就是递归+callback, 尽管这种做法并不优雅, 但总算是解决问题了, 两位提供的方案都给我了很大的启发, 我会根据两位提供的方法去重构一下这部分的代码. 再次感谢.
    About     Help     Advertise     Blog     API     FAQ     Solana     2958 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 67ms UTC 15:20 PVG 23:20 LAX 08:20 JFK 11:20
    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