推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
abcbuzhiming

求教,如何使用 promise 完成循环状态下的链式异步任务

  •  
  •   abcbuzhiming · Apr 7, 2017 · 7114 views
    This topic created in 3348 days ago, the information mentioned may be changed or developed.
    Promise 能像下面这样顺序完成链式异步任务

    promise1().then(function(data) {
    console.log(data);
    return promise2();
    })
    .then(function(data) {
    console.log(data);
    return promise3();
    })
    .then(function(data) {
    console.log(data);
    return '结束了吧'
    }).then(function(data) {
    console.log(data);
    });
    }
    但是这里存在一个问题, promise2 和 promise3 都必须是在外部预定义好的。

    但是现在我有这么一个需求,我可能有一大批 promise 对象,这些 promise 对象都是按一定算法用循环生成的。结果这就遇到了坑,我试图这么干

    function axiosLoop(index) {
    /*
    XXXXXX
    */
    return axiosObj;
    }
    var objTemp = null;
    for (var i = 0; i < 10; i++) {
    objTemp = axiosLoop(i).then(function (data) {
    console.log(data);
    return axiosLoop(i+1); //这么干是不行的,因为这个 i 值是引用外部的 i ,它会直接演变成最大的 10
    }).catch(function (error) {
    console.log(error);
    });
    }

    =========
    我该怎么解决这个问题,这个问题不能使用类似 promis.all()来执行,因为我一定要保证有序执行
    13 replies    2017-04-09 14:31:53 +08:00
    freeminder
        1
    freeminder  
       Apr 7, 2017
    再包一层
    objTemp = axiosLoop(i).then((function (idx){
    return function(data){
    console.log(data);
    return axiosLoop(idx);
    }
    })(i+1)).catch(function (error) {
    console.log(error);
    });
    nino
        2
    nino  
       Apr 7, 2017
    AlisaDestiny
        3
    AlisaDestiny  
       Apr 7, 2017
    @freeminder 跟我第一感一样。用闭包。
    bdbai
        4
    bdbai  
       Apr 7, 2017 via Android
    支持 ES6 的话,把 for 里面的 var 改成 let 。
    hythyt9898
        5
    hythyt9898  
       Apr 7, 2017 via iPhone
    为何不用 async/await ?
    mogita
        6
    mogita  
       Apr 7, 2017 via iPhone
    比较脏难维护和扩展,但能解燃眉之急的方案:引 deasync 包,把请求封装成一个同步方法。
    需要额外学习、要求特定 nodejs 版本或使用编译工具,但优雅稳定的方案: async/await 。
    abcbuzhiming
        7
    abcbuzhiming  
    OP
       Apr 7, 2017
    @freeminder
    @AlisaDestiny
    @ck65
    谢谢楼上各位,奋斗了一晚上,终于在重新理解 promise 模型和闭包变量作用域的基础上,按照 freeminder 的方法搞定了。折腾死了,我终于明白为啥 Promise 仅仅出来了两年就被 async/await 干掉了, 12 万分的希望 async/await 早日在前端普及吧,再也不想拿 Promise 写东西了
    imdoge
        9
    imdoge  
       Apr 8, 2017
    可以用 reduce 来, arr.reduce((promise, item) => { return promise.then(() => asyncReq(item)), asyncReq1()}
    xieranmaya
        10
    xieranmaya  
       Apr 8, 2017
    [p1,p2,p3].reduce((seq,next) => seq.then(value=>next()), Promise.resolve())

    说白了有点像 x = x + n
    你看啊: seq = seq.then(value => task(value)
    是不是很像
    bdbai
        11
    bdbai  
       Apr 8, 2017 via Android
    @abcbuzhiming Promise 活的好好的,没被干掉吧。
    嫌原生 Promise 不好用可以试试 bluebird 。
    xieranmaya
        12
    xieranmaya  
       Apr 9, 2017
    @abcbuzhiming
    @bdbai 说的很对, Promise 并没有“被” async/await 干掉,相反, async/await 是基于 Promise 的,如果你不深入理解 Promise ,你也不会真正理解 async/await ,事实上, async 函数的调用就是返回 Promise ,而 await 操作符后面必须是一个 Promise 对象,这意味着你要用 async/await 的时候,必须还是要自己实现一些返回 Promise 的函数
    LeoEatle
        13
    LeoEatle  
       Apr 9, 2017 via iPhone
    最简单的处理方案就是,用 let
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1196 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 70ms · UTC 23:44 · PVG 07:44 · LAX 16:44 · JFK 19:44
    ♥ Do have faith in what you're doing.