承诺所有异步操作

时间:2016-10-25 11:57:29

标签: javascript asynchronous promise bluebird

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

  

1。一次操作需要1秒才能执行
   2。其他操作需要10个   秒执行

我想使用promise.all这两个操作将并行执行(我知道在js中没有多路径的概念......) 并且都在同一个步骤上执行, 当我使用诺言时,我期望op1将在op2 之前完成,这不会发生...任何想法我在这里缺少什么? (假设op1在我的服务器中保存了一些小的东西(1秒)op2(10秒),当我在1秒后检查时,我没有看到op1在两个完成之后完成......)。 我知道,在两者完成(解决)之后,所有的承诺都将完成。

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

3 个答案:

答案 0 :(得分:2)

  

我想使用promise.all这两个操作将并行执行...

请注意,使用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需要一秒钟而op2需要10秒而我们假设它们都成功,那么您的回调将在10秒后执行(op2完成时)。如果您知道op1只需要一秒钟,那么op1可能会在您调用Promise.all回调之前几秒钟完成。

如果您想在op1完成时收到通知,请在then上使用op1。您可以单独执行此操作,也可以执行此操作,并在完成任务时使用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);
  });
}

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

答案 1 :(得分:-1)

  

当我使用promise时,我希望op1将在op2之前完成,这不会发生...知道我在这里缺少什么吗?

数组块中的所有单个诺言都将异步执行,并且仅在所有诺言成功解析后才进入.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'] 
    });

答案 2 :(得分:-1)

要使 op1在op2之前完成,可以使用以下选项之一- 1.承诺链接说明了here 2. ES6中提供的发电机。 3. ES7中提供的Async-Await

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