【问题标题】:How to chain promises in for loop in vanilla javascript如何在香草javascript中的for循环中链接承诺
【发布时间】:2017-08-25 02:18:25
【问题描述】:

如果我正在执行如下所示的异步调用,如何将它们与 Promise 链接起来,以便我可以按顺序执行操作?在这个例子中,最终发生的事情是arr 将推动项目乱序。我更喜欢有承诺的答案,但只要有效,任何事情都会做

var fbArrOfAlbumNames = ['Profile Pictures', 'Cover Photos', 'Mobile Uploads'];
var arr = [];
for(var x = 0; x < fbArrOfAlbumNames.length; x++) {
  (function(cntr) {
    FB.api('/' + fbArrOfAlbumNames[cntr] + '/photos/', {fields: 'picture,album'}, function(response) {
      arr.push(response);
    }
  })(x);
}

【问题讨论】:

  • 您的意思是这段代码是ajaxCallFbAPI(someArgs, function(err, data) {...}); 您在问题中显示的内容看起来不像典型的异步API。
  • 链接异步代码以同步运行有点违背了它的目的。我要尝试的第一件事是使用Promise.all() 并在它们全部完成后将您的响应添加到您的数组中,这至少允许它运行的速度与最慢的调用一样慢,而不是所有它们的累积时间。
  • @jfriend00 是的,你是对的。我故意简洁,因为它的细节并不重要。可以是任何异步调用。
  • 我和@jfriend00有同样的想法,他的例子真的很好。
  • 嗯,细节很重要。为什么不将问题中的示例修复为至少是合法的异步调用,以便人们可以更具体地为您提供帮助(您可以使用“编辑”链接来修复它)。一般来说,当你展示你的实际代码时,你会得到更好、更相关和更详细的答案,而不是一些假想的代码示例。魔鬼往往在细节中,只有当我们看到您的实际代码时,我们才能彻底。此外,当我们看到真正的问题和真正的代码时,我们更有可能为您提供您甚至不知道的问题。

标签: javascript promise es6-promise


【解决方案1】:

假设您的 ajax 调用实际上可以并行运行并且您只希望结果按顺序排列,那么您可以承诺 ajax 函数并使用Promise.all() 来按顺序获得所有结果:

// promisify the ajax call
function fbAPIPromise(path, args) {
    return new Promise(function(resolve, reject) {
        FB.api(path, args, function(results) {
            if (!result) return resolve(null);
            if (result.error) return reject(result.error);
            resolve(result);
        });
    });
}

var promises = [];
for (var x = 0; x < 10; x++) {
     promises.push(fbAPIPromise('/' + fbArrOfAlbumNames[x] + '/photos/', {fields: 'picture,album'});
}
Promise.all(promises).then(function(results) {
     // results is an array of results in original order
}).catch(function(err) {
     // an error occurred
});

【讨论】:

  • 更新了代码示例以使用您的实际 FB.api() 调用,因为您将其添加到您的问题中。
  • 我现在明白@guest271314 之前所说的了。如果我尝试在fbAPIPromise() 中设置我的值,比如fbPicArr.thumb.push(response.data[0].picture),那么它仍然会出现故障。我想我可以在Promise.all 之后遍历它,但我想知道是否有办法在fbAPIPromise() 内完成所有操作
  • @lazyboy78 - 首先,您决定是否可以并行运行您的操作,因为这将使您获得更快的最终结果。如果您并行执行它们,那么每个单独的操作都将以相对于其余操作的不确定顺序完成。仍然有一些方法可以在那里按顺序处理它们(但不使用.push()),但坦率地说,遍历已经有序的最终结果更容易。这将是建议。 results.forEach() 会让你按顺序处理它们。
  • @lazyboy78 - 您也可以执行promises.push(fbAPIPromise(...).then(...)) 并在您的.then() 处理程序中处理结果并返回该项目的结果,然后这就是最后results 数组中的内容(已处理)。
  • 你遍历最终结果似乎是最好的解决方案。只是出于好奇想知道是否还有其他选择。很棒的技巧,我觉得在使用带有 Promise 的循环方面知识渊博了很多
猜你喜欢
  • 2020-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-01
  • 2016-10-11
  • 2015-12-18
  • 1970-01-01
  • 2017-12-10
相关资源
最近更新 更多