繁体   English   中英

使用ES6的顺序迭代Promise

[英]Sequential iteration using ES6 promises

我期望在node.js下面的代码将按以下顺序打印输出

1000
2000
3000
4000
"All tasks completed"

而是按以下提到的顺序打印

"All tasks completed"
1000
2000
3000
4000

编码

'use strict';

var tasks = [1000, 2000, 3000, 4000];
var promise = Promise.resolve();


function test() {
  tasks.forEach(function(task) {
    promise = promise.then(function() {
      setTimeout(function() {
        console.log(task);
      }, task);
    });
  });
}

test();

promise.then(function() {
  console.log('All tasks completed');
});

需要修改什么,以便最后打印“所有任务已完成”。

  1. 我的示例使用ES6 Promise,而不使用bluebird。
  2. 我也不是在问关于诺言的一般性问题,而是关于一个具体的例子。

在所有then函数中,您什么都不返回,而是触发异步操作。 因此,promise链与异步操作无关。 这就是为什么您无法按需要控制流量的原因。

您可能要做的是,从每个then处理程序中返回一个Promise,仅当异步操作完成时才解决此问题,如下所示

  tasks.forEach(function(task) {
    promise = promise.then(function() {
      return new Promise((resolve, reject) => {
        setTimeout(function() {
          console.log(task);
          resolve();
        }, task);
      })
    });
  });

请记住, 这将一次触发异步操作 例如,一秒钟后,它将打印1000,第二个异步操作将开始,它将等待两秒钟,然后打印2000,依此类推。 基本上,您的程序将在大约10秒钟(1 + 2 + 3 + 4秒)后退出,因为我们将依次执行所有异步功能。


但是, 如果您希望所有人都立即触发 ,请使用Promise.all ,就像这样

'use strict';

var tasks = [1000, 2000, 3000, 4000];

function test() {
  return Promise.all(tasks.map(function(task) {
    return new Promise((resolve, reject) => {
      setTimeout(function() {
        console.log(task);
        resolve();
      }, task);
    })
  }));
}

test().then(function() {
  console.log('All tasks completed');
});

现在,所有异步功能都立即被触发,因此一秒钟后,将打印1000,两秒钟后将打印2000,依此类推。 您的程序将在4秒钟后完成所有异步操作,因为所有异步操作都会立即启动。

目前,这是我发现的唯一一种以顺序AND阻塞方式迭代promise数组的方法...

请检查代码示例...

const list = [1,2,3,4,5];

数字越高,兑现承诺的速度越快

const functionWithPromise = item => { 
  return new Promise((resolve) =>{
    setTimeout(resolve, 6000 - (1000 * item ) , item);
})}

Promise.all返回带有promise的数组

const getData = async () => Promise.all(await iterateSequentiallyPromiseArray(list,functionWithPromise));

for循环是唯一以阻塞方式迭代的循环

const iterateSequentiallyPromiseArray = async (array, fn) => {
    try {
      const results = [];
      for (let i = 0; i < array.length; i++) { 
        console.log('Start with index: ', i);
        const r = await fn(array[i]);
        console.log('in promise iteration', r);
        results.push(r);
      }
      return results; // will be resolved value of promise
    } catch (err) {
      console.log('_processArray');
      throw err;
    }

};

开始连锁

getData().then(console.log);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM