Javascript Promise.all:解析值的顺序

Javascript Promise.all:解析值的顺序,javascript,promise,es6-promise,Javascript,Promise,Es6 Promise,查看它时,看起来像是传递给Promise的then()回调的值。所有这些值都按承诺的顺序包含。例如: 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? }); 任何人都可以引用说明

查看它时,看起来像是传递给Promise的
then()
回调的
值。所有这些值都按承诺的顺序包含。例如:

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?
});
任何人都可以引用说明
值的顺序的规范吗


PS:运行这样的代码表明这似乎是真的,尽管这当然不是证据——这可能是巧合。

是的,
结果中的值与
承诺中的值顺序相同

有人可能会引用,尽管由于使用了迭代器api和泛型promise构造函数,它有点复杂。但是,您会注意到每个解析器回调都有一个
[[index]]
属性,该属性是在promise数组迭代中创建的,用于设置结果数组上的值。

按照您链接到的规范,将一个作为参数,并在内部调用它,后者使用循环
iterable

解析是通过以下方式实现的:每个解析的承诺都有一个内部
[[Index]]]
插槽,该插槽在原始输入中标记承诺的索引


所有这一切都意味着,给定传递给Promise的iterable,输出是严格有序的。All()是严格有序的(例如,数组)

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

//用于显示结果
const write=msg=>{
document.body.appendChild(document.createElement('div')).innerHTML=msg;
};
//不同速度异步操作
const slow=新承诺(解析=>{
设置超时(解析,200,“慢”);
});
const instant=‘instant’;
const quick=新承诺(解决=>{
setTimeout(解析,50,‘快速’);
});
//无论首先解决的是什么,顺序都将保留
承诺。所有([缓慢、即时、快速])然后(回复=>{
map(response=>write(response));

});
正如前面的答案所述,
Promise.all
使用与原始Promises的输入顺序对应的数组聚合所有解析值(请参阅)

然而,我想指出,订单只保留在客户端

对开发者来说,看起来承诺是按顺序履行的,但实际上,承诺的处理速度不同。当您使用远程后端时,了解这一点很重要,因为后端可能会以不同的顺序接收您的承诺

下面是一个使用超时来演示问题的示例:

承诺。所有

const myPromises=[
新承诺((resolve)=>setTimeout(()=>{resolve('A(slow)');console.log('A(slow)},1000)),
新承诺((解析)=>setTimeout(()=>{resolve('B(sleer)');console.log('B(sleer)},2000)),
新承诺((resolve)=>setTimeout(()=>{resolve('C(fast)');console.log('C(fast)},10))
];

Promise.all(myPromises).then(console.log)
一个iterable如何不严格订购?任何iterable都是按照其生成值的顺序进行“严格排序”的。请注意,Firefox是唯一一款能够正确实现iterable的浏览器。如果你将一个iterable传递给Promise.all,Chrome当前将抛出一个excation。此外,我不知道目前有任何userland promise实现支持传递iterable,尽管当时很多人对此进行了辩论并决定反对。@BenjaminGruenbaum难道不可能有一个iterable在迭代两次后产生两个不同的顺序吗?例如,一副牌在迭代时以随机顺序生成牌?我不知道“严格有序”是否是这里正确的术语,但并非所有的iterables都有固定的顺序。因此,我认为有理由说迭代器是“严格有序的”(假设这是一个正确的术语),但iterables不是。@JLRishe我想你是对的,迭代器确实是有序的,iterables不是。值得注意的是,承诺不会连锁。虽然你会以同样的顺序得到决议,但无法保证承诺何时兑现。换句话说,
Promise.all
不能用于依次运行承诺数组。加载到迭代器中的承诺需要彼此独立,才能按预期工作。奇怪的是,我今天在youtube上看到一段视频,视频中说输出顺序由第一个解决者决定,然后是第二个,然后……我猜视频操作是错的?@RoyiNamir:显然是。@Ozil Wat?当所有承诺兑现时,决议的时间顺序绝对不重要。结果数组中的值顺序与承诺的输入数组中的值顺序相同。如果不是,您应该切换到适当的承诺实现。回答很好,特别是使用PQUEI我需要一个顺序承诺队列,但如果必须从结果sql记录执行,该如何操作?为了什么?然而,在ES2017中没有其他选择我们的ES2018?PQUE帮助了我!谢谢!:)