Javascript Promise.all和连续运行Promises之间的区别?
说我有一大堆承诺Javascript Promise.all和连续运行Promises之间的区别?,javascript,Javascript,说我有一大堆承诺 const promises = [ /*...*/ ]; 我希望当所有的承诺都解决了的时候会发生一些事情。以下两种方法的区别是什么: 使用Promise.all const allDonePromise = Promise.all(promises); 连续履行承诺 async function allPromises(promisesArray) { const results = []; for (const promise of promisesArra
const promises = [ /*...*/ ];
我希望当所有的承诺都解决了的时候会发生一些事情。以下两种方法的区别是什么:
Promise.all
const allDonePromise = Promise.all(promises);
async function allPromises(promisesArray) {
const results = [];
for (const promise of promisesArray) {
results.push(await promise);
}
return results;
}
const allDonePromises = allPromises(promises);
是
Promise.all
只是一个做allPromises
所做的事情的内置程序,或者是引擎盖下发生了什么事情来做出承诺。一切都更快。在哪里可以找到有关Promise.all
的内部信息?您可以在中找到Promise.all
的规范
您自己的实现确实在做正确的事情。具体差异如下:
上述规范在第25.4.4.1.1.r点规定,然后
将在每个承诺上调用。这些调用是同步进行的(注意:不是它们的回调)。无论何时任何承诺得到解决,剩余的承诺都会减少(参见步骤2.10)。每当它变为零时,promise.all
返回的promise将被解析(注意:同步!)
现在假设你有一个一百万承诺的数组,第一个承诺的解析时间最长,那么你的函数仍然需要执行9999999等待函数返回,而规范中的算法在第一个承诺解析之前已经处理了9999999承诺的解析,在第一个承诺最终解决后,就没有什么可做的了
例如,您可以在中看到这一点(计数通过递增进行):
shaka.polyfill.Promise.all=函数(其他){
var p=new shaka.polyfill.Promise();
如果(!其他.长度){
p、 解决([]);
返回p;
}
//结果数组的顺序必须与承诺数组的顺序相同
//传递给all()。因此我们预先分配数组并记录如何分配
//许多人已经解决了。只有当所有人都解决了问题时,承诺才会得到回报
//它自己解决了。
var计数=0;
var值=新数组(其他.长度);
var resolve=函数(p,i,newValue){
shaka.asserts.assert(p.state_!=shaka.polyfill.Promise.state.RESOLVED);
//如果数组中的一个承诺被拒绝,则此承诺将被拒绝
//拒绝和忽略新值。在这种情况下,值数组
//它的内容在所有承诺兑现之前仍在记忆中
//在数组中已完成。
if(p.state==shaka.polyfill.Promise.state.PENDING){
值[i]=新值;
计数++;
if(count==values.length){
p、 解决问题(价值观);
}
}
};
var reject=p.reject_uu.bind(p);
对于(变量i=0;i
但请注意,浏览器实现是不同的。上面的polyfill只是可能的实现之一
请注意,您的函数不是“连续运行承诺”。这些承诺正在“运行”*不管你是否对它们做了些什么:它们在你构建它们的时候就完成了它们的工作
唯一连续化的事情是你开始看(即等待)各自承诺决议的时刻。规范似乎暗示,实现应该从一开始就监听所有承诺的resolve回调。这不能通过循环中的wait
实现(当然,您可以这样做,但是您需要重复调用async
函数,每个承诺调用一次,这将不会给您带来任何使用wait
overthen
的好处,因为您需要对async
函数返回的承诺应用then
)
然后在这个和参数验证方面还有一些其他(明显的)差异。尤其是ECMA规范说明:
all
函数要求其this
值是支持Promise
构造函数参数约定的构造函数
*承诺不会真正“运行”,因为承诺是对象而不是函数。可能正在运行的是在创建承诺对象时启动的某个异步任务。承诺构造函数回调可能会调用异步API(如setTimeout
,fetch
,…)这可能会导致异步调用resolve
。最好将此中间状态作为“挂起”(而不是“运行”)的承诺调用。相关:相关问题不会询问性能和内部差异。promise.all允许“一次”运行所有承诺-链接承诺以串联方式运行…但是,您的allPromises
函数实际上根本没有链接承诺,因为所有承诺“一次”执行 anyway@JaromandaX承诺执行者不是一调用承诺构造函数就开始运行吗?allPromises
代码不是相当于wait promise1;wait promise2;wait promise3;
这相当于promise1。然后(()=>promise2)。然后(()=>promise3);
?
shaka.polyfill.Promise.all = function(others) {
var p = new shaka.polyfill.Promise();
if (!others.length) {
p.resolve_([]);
return p;
}
// The array of results must be in the same order as the array of Promises
// passed to all(). So we pre-allocate the array and keep a count of how
// many have resolved. Only when all have resolved is the returned Promise
// itself resolved.
var count = 0;
var values = new Array(others.length);
var resolve = function(p, i, newValue) {
shaka.asserts.assert(p.state_ != shaka.polyfill.Promise.State.RESOLVED);
// If one of the Promises in the array was rejected, this Promise was
// rejected and new values are ignored. In such a case, the values array
// and its contents continue to be alive in memory until all of the Promises
// in the array have completed.
if (p.state_ == shaka.polyfill.Promise.State.PENDING) {
values[i] = newValue;
count++;
if (count == values.length) {
p.resolve_(values);
}
}
};
var reject = p.reject_.bind(p);
for (var i = 0; i < others.length; ++i) {
if (others[i].then) {
others[i].then(resolve.bind(null, p, i), reject);
} else {
resolve(p, i, others[i]);
}
}
return p;
};