Promise.all:解析的值的顺序Promise.all:解析的值的顺序(Promise.all

2019-05-10 10:47发布

看着MDN它看起来像values传递给then() Promise.all的回调包含了承诺的顺序值。 例如:

var somePromises = [1, 2, 3, 4, 5].map(Promise.resolve);
return Promise.all(somePromises).then(function(results) {
  console.log(results) //  is [1, 2, 3, 4, 5] the guaranteed result?
});

任何人都可以举一个规范,说明以何种顺序values应该是?

PS:运行代码一样,表明这似乎是真实的,尽管那是当然的没有证据 - 它可能是巧合。

Answer 1:

不久, 订单将被保留

下面您联系,规范Promise.all(iterable)需要一个iterable (即,支持对象Iterator接口)作为参数和以后调用PerformPromiseAll( iterator, constructor, resultCapability)用它,后者环过iterable使用IteratorStep(iterator)
这意味着,如果如果你可迭代中传递给Promise.all()是严格有序的,他们仍然会被责令一次通过。

解决是通过实施Promise.all() Resolve ,其中每个解决承诺具有内部[[Index]]槽,这标志着在原始输入的承诺的索引。


所有这些都意味着输出被严格,只要该输入是严格有序的(例如,阵列)有序作为输入。

您可以在下面的小提琴(ES6)动作看到这一点:

 // Used to display results const write = msg => { document.body.appendChild(document.createElement('div')).innerHTML = msg; }; // Different speed async operations const slow = new Promise(resolve => { setTimeout(resolve, 200, 'slow'); }); const instant = 'instant'; const quick = new Promise(resolve => { setTimeout(resolve, 50, 'quick'); }); // The order is preserved regardless of what resolved first Promise.all([slow, instant, quick]).then(responses => { responses.map(response => write(response)); }); 



Answer 2:

是的,在数值results是在相同的顺序promises

也许有人会举上ES6规范Promise.all ,虽然这是一个有点令人费解由于使用迭代器API和通用承诺的构造。 然而,会注意到,每个分解器回调具有[[index]]这是在许阵列迭代创建和使用的结果阵列上设置的值的属性。



Answer 3:

如前面的答案已经指出的那样, Promise.all聚合所有解析值与对应于原始承诺的输入顺序的阵列(见汇总承诺 )。

不过,我想指出的是,该命令只保存在客户端!

为了开发它看起来像承诺是为了满足,但在现实中,承诺以不同的速度进行处理。 因为后端可能会收到不同的顺序对您的承诺这是要知道,当你与远程后端工作的重要。

下面是一个说明通过使用超时问题的例子:

Promise.all

 const myPromises = [ new Promise((resolve) => setTimeout(() => {resolve('A (slow)'); console.log('A (slow)')}, 1000)), new Promise((resolve) => setTimeout(() => {resolve('B (slower)'); console.log('B (slower)')}, 2000)), new Promise((resolve) => setTimeout(() => {resolve('C (fast)'); console.log('C (fast)')}, 10)) ]; Promise.all(myPromises).then(console.log) 

在上面所示的代码,三个承诺(A,B,C)被给予Promise.all 。 三个承诺执行以不同的速度(C是最快的,B是最慢的)。 这就是为什么console.log承诺的陈述顺序显示出来:

C (fast) 
A (slow)
B (slower)

如果承诺是AJAX调用,然后远程后端将在此为了获得这些值。 但在客户端Promise.all确保结果根据的原始位置有序myPromises阵列。 这就是为什么最后的结果是:

['A (slow)', 'B (slower)', 'C (fast)']

如果你想也保证你的承诺的实际执行,那么你就需要像无极队列的概念。 下面是使用一个例子对队列 (注意,你需要用函数的所有承诺):

连续无极队列

const PQueue = require('p-queue');
const queue = new PQueue({concurrency: 1});

// Thunked Promises:
const myPromises = [
  () => new Promise((resolve) => setTimeout(() => {
    resolve('A (slow)');
    console.log('A (slow)');
  }, 1000)),
  () => new Promise((resolve) => setTimeout(() => {
    resolve('B (slower)');
    console.log('B (slower)');
  }, 2000)),
  () => new Promise((resolve) => setTimeout(() => {
    resolve('C (fast)');
    console.log('C (fast)');
  }, 10))
];

queue.addAll(myPromises).then(console.log);

结果

A (slow)
B (slower)
C (fast)

['A (slow)', 'B (slower)', 'C (fast)']


文章来源: Promise.all: Order of resolved values