【问题标题】:How to run after all javascript ES6 Promises are resolved解决所有 javascript ES6 Promise 后如何运行
【发布时间】:2014-12-25 09:52:23
【问题描述】:

我正在替换一些使用 jQuery Deferred 对象的旧代码,并且我正在使用 Bluebird/ES6 Promises 重写。

如果我有多个异步调用,如何在所有 promise 都解决后触发函数。

使用 jQuery Deferreds 会是这样的:

var requests = [...]; //some arbitrary data that is iterated to generate multiple ajax requests
var promises = [];
resuests.forEach(function(endpoint) {
    promises.push($.ajax({url: endpoint}));
});

$.when.apply($, promises).then(function() {
    alert('all promises complete!');
});

如何使用 ES6 Promise 语法重写它?

【问题讨论】:

  • 使用 jQuery 的 promise 语法可以是 $.when.apply($, requests.map($.get)).then(... - 更干净

标签: javascript promise bluebird es6-promise


【解决方案1】:

使用Promise.all。请注意,它将一个可迭代对象(例如 Array)作为其参数,与 $.when 不同,因此不需要 .apply

您还需要使用 Promise.resolve(thejQueryDeferred) 将 jQuery Deferred 转换为原生 ES6 Promise。 编辑:这是通过调用 Promise.all 隐式完成的,因此实际上是可选的。

完整代码:

var requests = [...]; //some arbitrary data that is iterated to generate multiple ajax requests
var promises = [];
requests.forEach(function(endpoint) {
    var nativePromise = Promise.resolve($.ajax({url: endpoint})); // if you want to make it clear that you're converting from jQuery Deferred to ES6 promise!
    promises.push(nativePromise);
});

Promise.all(promises).then(function() {
    alert('all promises complete!');
});

【讨论】:

  • 谢谢,已更新。请注意,只需 Promise.resolve(thejQueryDeferred) 就足以将 jQuery Deferred 转换为 ES6 Promise(Promise.resolve 检查 then 属性并采取相应措施)。
  • @dfsq 实际上 - 它是。原生 Promise 是围绕 Promises/A+ 构建的,而 Promises/A+ 又以这样一种方式构建,可以使用 jQuery Promise。这是有意的。
  • 至于.resolve 注释——你实际上不需要这样做,当一个本地的promise 使用一个外部的thenable 时,Promise.resolve 会自动为你完成。您可以在规范(甚至是您链接到的 MDN)中看到这一点。
  • @BenjaminGruenbaum 好点。我应该坚持自己的立场:-)我将坚持在我的答案中进行显式转换,因为我更喜欢清晰,但谢谢你的有效观点。
  • 记录一下——所有的 promise 方法都这样做,.then 这样做,等等。同化是规范中的核心概念。否则 - 不同的承诺库之间的互操作将非常困难:)
【解决方案2】:

由于这被标记为,除了您已经在这里获得的两个好的解决方案之外,还有一种更“蓝鸟”的方式:

var requests = [...];

Promise.map(requests, $.get).then(function(results){
    alert('all promises complete!');
});

这可能很简单。

正如其他人所指出的,原生 es6 方式是使用 Promise.all,而不是 Promise.resolve 或需要显式创建。使用原生 Promise 最简洁的方式可能是:

var requests = [...];
Promise.all(requests.map($.get)).then(function(results){

});

【讨论】:

  • 很好的答案,我很欣赏 Bluebird 的语法。我目前正在使用 Bluebird,但可能会坚持使用原生语法,因为当主要浏览器正式支持 ES6 时,我可能会考虑删除 Bluebird。
猜你喜欢
  • 2018-12-31
  • 1970-01-01
  • 2021-04-15
  • 1970-01-01
  • 2017-12-29
  • 2021-05-17
  • 2017-06-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多