javascript - 如何同时实现 Javascript Promise.all 有趣的功能

标签 javascript parallel-processing ecmascript-6 es6-promise

据我了解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/

相关文章:

带有参数的 javascript 抽象回调

javascript - 单选切换按钮问题

javascript - Chart.js 水平条宽度

algorithm - 有限数量的 worker 需要一种新的项目管理算法

javascript - 深度子类型的流错误

javascript - 在 HTML 页面的模态窗口中显示图像

c++ - 英特尔 MIC 上的英特尔 TBB 和 Cilk Plus 线程亲和性

r - 是否使用R中的detectCores函数指定并行处理的核心数?

ecmascript-6 - es6 的 Webpack 路径问题

javascript - ReactJS 和 Express with Axios 返回 404 错误消息