据我了解Promise.all根据文档,可以同时运行两个或多个函数并等待所有函数完成。所以我尝试了这个:
function execute(id, max) {
console.log('starting ' + id);
console.time(id);
var sum = 0;
for(var i = 0; i < max; i ++) {
sum += i;
}
console.timeEnd(id);
return sum;
}
console.log("Declaring p1");
var p1 = Promise.resolve(() => execute("p1", 10000));
console.log("Declaring p2");
var p2 = Promise.resolve(() => execute("p2", 100000));
console.log("Calling Promise.all");
console.time("all");
Promise.all([p1, p2]).then((values) => console.log("Then: " + values));
console.timeEnd("all");
但是,我得到的(在 Chrome 中运行)是这样的:
Declaring p1
Declaring p2
Calling Promise.all
all: 0.599ms
Then: () => execute("p1", 10000),() => execute("p2", 100000)
很明显,不仅函数没有运行,then
方法也没有运行它们,结果也没有运行。
即使我用原始函数调用替换 promise ,我也会得到相同的结果:
function execute(id, max) {
console.log('starting ' + id);
console.time(id);
var sum = 0;
for(var i = 0; i < max; i ++) {
sum += i;
}
console.timeEnd(id);
return sum;
}
console.log("Calling Promise.all");
console.time("all");
Promise.all([() => execute("p1", 10000), () => execute("p2", 100000)])
.then((values) => console.log("Then: " + values));
console.timeEnd("all");
输出是:
Calling Promise.all
all: 0.274ms
Then: () => execute("p1", 10000),() => execute("p2", 100000)
所以,我认为我误解了 Promise.all
的用法。如何使用 Promises 执行并行处理?
谢谢
拉斐尔·阿方索
最佳答案
Promise.all 接受一系列 Promise,并在所有 Promise 都得到解决或其中一个被拒绝后立即解决。但按照规范,Promise 并不是异步的,实际上,情况恰恰相反:Promise executor 立即执行。因此,如果所有执行器都是同步的,那么您的 promise 链也是同步的。
也许这有助于理解它是如何工作的:
function execute(id, max) {
console.log('starting ' + id);
console.time(id);
var sum = 0;
for(var i = 0; i < max; i ++) {
sum += i;
}
console.timeEnd(id);
return sum;
}
console.log("Declaring p1");
var p1 = Promise.resolve(execute(1, 10));
console.log("Declaring p2");
var p2 = new Promise((resolve, reject) => {
console.log('setting timeout..');
setTimeout(() => resolve(execute(2,10)), 2000);
})
console.log("Calling Promise.all");
console.time("all");
console.time('results');
Promise.all([p1,p2])
.then((results) => {
console.log('all results', results);
console.timeEnd('results');
})
.catch(console.error.bind(console));
console.timeEnd("all"); // Promise.all returns immediately
这就是输出:
Declaring p1
starting 1
1: 0.016ms
Declaring p2
setting timeout..
Calling Promise.all
all: 0.097ms
starting 2
2: 0.002ms
all results [45, 45]
results: 2001.144ms
通常,在调用一些异步API时会使用Promise。但如果你真的想异步运行你自己的 javascript,你需要使用 Web Workers 或其他东西,具体取决于你的平台。
编辑:一些关于 Web Workers 和 Promises 的快速谷歌搜索,有一个漂亮的库 promise-worker 。我所说的好看是指 100% 的覆盖率和自动化的浏览器测试。如果您想走这条路,可能值得检查,甚至安装。
关于javascript - 如何同时实现 Javascript Promise.all 有趣的功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37790749/