【问题标题】:chaining nested promises in a loop在循环中链接嵌套的 Promise
【发布时间】:2014-07-09 06:06:06
【问题描述】:

我对 Promise 有点陌生,并且被困在下面的练习中。

我有一个值数组,我想对每个值执行一个异步调用。 在回调中,我想对第一次调用的结果执行另一个调用。

基本上,我的挫败感如下: 执行顺序应该是 '1x2x3x' 但顺序是 '123xxx'

换句话说,当第一个承诺的子/嵌套承诺尚未完成时,循环已经进入下一次迭代..

var values = ["1", "2", "3"];

function do(val) {
  var deferred = Q.defer();


  asyncCall(val)
  .then( function( response ) {
    console.log(val); 
    asyncCall(response)
    .then( function ( response ) {
      console.log('x');
      deferred.resolve(true)
    });
  });

  return deferred.promise;
}

var result = do(values[0]);

values.forEach( function(f) {
  result = result.then(do(f));
}

可能有一个简单的解决方案,但我坚持下去。

【问题讨论】:

    标签: javascript loops nested promise


    【解决方案1】:

    你不需要 deferred,那是自 promises 链以来你所拥有的 deferred anti pattern

    此外,如果您希望它等待解决,您必须从 .then 处理程序返回一个承诺。

    您可以简单地使用 for 循环:

    function do(val) {
    
      var q = Q();
      for(var i = 0; i < val; i++){
        q = q.then(asyncCall.bind(null,i))
             .then(console.log.bind(console))
             .then(console.log.bind(console,"x"));
      }
    
      return q; // in case you want to chain
    }
    

    fiddle.

    注意:绑定只是固定函数调用的值。在这种情况下,由于第一个参数(this 值)为 null,它的行为类似于 function(fn,arg){ return function(arg){ return fn(arg); }},也就是说,它将函数调用转换为“部分应用程序” - 更多信息请参见 the MDN docs

    【讨论】:

    • 感谢您的回答。但我不完全明白。我删除了延迟模式并重构了我的代码,如下所示: (函数(响应){console.log(响应);});我可以在第一个“then”中省略返回,但是 asyncCall2 的承诺不会传递给第二个 then..
    • @strai 你能在 jsfiddle.net 上创建一个小提琴来说明这个问题吗?这很难读
    猜你喜欢
    • 2018-05-20
    • 2023-04-04
    • 2017-12-23
    • 1970-01-01
    • 2018-10-01
    • 2016-06-10
    • 2017-08-08
    • 2018-05-26
    • 1970-01-01
    相关资源
    最近更新 更多