承诺所有异步操作

Promise all async operations

我有两个异步操作,执行时间不同,比方说

1 . one operation take 1 sec to execute
2 . other operation take 10 sec to execute

我想用promise.all两个操作并行执行(我知道在js中没有多线程的概念...) 并且都执行相同的步骤, 当我使用 promise all 时,我 预计 op1 将在 op2 之前完成,但这并没有发生……知道我在这里错过了什么吗? (假设 op1 在我的服务器(1 秒)op2(10 秒)中保存了一些小东西,当我在 1 秒后检查时,我没有看到 op1 在两者完成后就完成了......)。 我知道 promise all will be finish after both will finished (resolved).

Promise.all([op1, op2]).then(values => { 
  console.log(values);
}, reason => {
  console.log(reason)
});

I want to use promise.all that the both operation will be excuted in parallel...

请注意,使用Promise.all与操作是否并行执行没有任何关系。它所做的只是给你一个承诺,当两个操作都成功时将得到解决,或者当 任一 操作失败时被拒绝。

让我们看看你的代码,看看评论:

Promise.all([op1, op2]).then(values => { 
  // This will happen when BOTH op1 and op2 are done
  console.log(values);
}, reason => {
  // This will happen when EITHER op1 OR op2 fails
  console.log(reason);
});

因此,如果 op1 花费 1 秒,op2 花费 10 秒,我们假设它们都成功,您的回调将在 10 秒后执行(当 op2 完成时) .如果您知道 op1 只需要一秒钟,那么很可能 op1 在您的 Promise.all 回调被调用之前完成了几秒钟。

如果您希望在 op1 完成时收到通知,请在 op1 上使用 then。您可以单独执行此操作,也可以执行此操作并在两者都完成时使用 Promise.all 获取通知。

这个例子,用setTimeout来模拟动作,可能会帮助你理解;在下面,op1 需要 100 毫秒,op2 需要 1000 毫秒。为简单起见,它假定两个操作都成功:

var start = Date.now();
var op1 = startOp1();
var op2 = startOp2();
op1.then(function() {
  // Fires when op1 is successful; doesn't care about op2
  console.log("op1 done after " + (Date.now() - start) + "ms");
});
op2.then(function() {
  // Fires when op2 is successful; doesn't care about op1
  console.log("op2 done after " + (Date.now() - start) + "ms");
});
Promise.all([op1, op2]).then(function() {
  // Fires when BOTH ops are successful
  console.log("both done after " + (Date.now() - start) + "ms");
});

function startOp1() {
  return new Promise(function(resolve) {
    setTimeout(function() {
      resolve();
    }, 100);
  });
}
function startOp2(flag) {
  return new Promise(function(resolve) {
    setTimeout(function() {
      resolve();
    }, 1000);
  });
}

注意:你说这两个操作都是异步的,所以我在上面假设了。

when I use promise all I expect that op1 will be finish before op2 which >doesn't happen...any idea what am I missing here?

数组块中的所有单个承诺都是异步执行的,只有在所有承诺都成功解决后才会进入 .then()。

尝试在 op1 和 op2 的定时器函数和解析函数之间分别使用 console.log('op1 done') 和 console.log('op2 done')。在控制台上看到的输出将是:

    op1 done //after 1 sec
    op2 done //after 10 sec
    ['op1 done','op1 done'] //immediately follows the above one

这应该会让您相信异步的本质。另外让我举一个更明显的例子,在下面的代码中,文本从浏览器中保存,Promise p2 在 Promise p1 之前完成。在 5 分钟的时间内(p1);该文件(使用 p2)将在 .then() 执行之前保存在系统中

    var FileSaver = require('file-saver');

    var p1 = new Promise((resolve, reject) => {
    setTimeout(resolve, 5 * 60 * 1000, 'Executed Promise p2');                         
    // 5 min timer
    }); 

    var p2 = new Promise((resolve, reject) => {
    var blob = new Blob(["Hello, world!"],
    {type:"text/plain;charset=utf-8"});                                                            
    FileSaver.saveAs(blob
    , "hello world.txt");
    // Not tested it; from page: https://github.com/eligrey/FileSaver.js/
    console.log('done with Promise p1');
    resolve('Executed Promise p1')
    }); 

    Promise.all([p1, p2]).then(values => { 
    console.log(values); // ['Executed Promise p1','Executed Promise p2'] 
    });

要在 op2 之前完成 op1,可以使用以下选项之一 - 1. Promise Chaining 解释 here 2. ES6 中提供的生成器。 3. ES7中提供的Async-Await

因为Promise.all()确保并行执行,而不是一个接一个地执行。