显示所有承诺的订单结果

jsh*_*303 3 javascript promise lodash

我是新的承诺.

我遇到了一个需要循环执行一系列任务并获取数据的情况.出于某种原因,我必须按顺序进行,并且必须使用promises来完成.但令我惊讶的是,结果只有最后一个元素而不是所有元素.

代码的简化版本

const _ = require('lodash');

const test = (name) => {
  return new Promise(function(resolve, reject) {
    //This is simplified from my actual code
    resolve(name);
  });
};

const testAll = (arr) => {
  //This chains and returns a series of functions with the order of arr, so that the can be executed in the order, not simultaneously
  let functions = _.map(arr, element => test.bind(null, element));
  //This reduces the functions and is supposed to return an array of all values
  return functions.reduce((fun1, fun2) => fun1.then(fun2), Promise.resolve([]));
}

const arr = ['promise1', 'promise2', 'promise3'];

testAll(arr)
.then(data => console.log(data));
Run Code Online (Sandbox Code Playgroud)

我期待输出(带订单):

promise1 
promise2
promise3
Run Code Online (Sandbox Code Playgroud)

但我真正得到的只是promise3.是因为Promise.resolve([])它不包括数组中的每个元素吗?

tri*_*cot 5

您似乎希望将单个结果累积到数组中.为此,您必须至少从每个承诺中捕获已解析的值.当你这样做时,fun1.then(fun2)你扔掉了承诺的价值fun1.要使用它,您需要对传递给then回调的参数执行某些操作.在你的情况下,你想要与承诺的值连接fun2().

但既然你有第一个,但仍然必须等待第二个,你可以从中受益Promise.all,像这样:

const testAll = (arr) => {
  let functions = arr.map(element => test.bind(null, element));
  return functions.reduce((prom, fun) => 
      prom.then(data => Promise.all(data.concat(fun())) ),
      Promise.resolve([])
  );
}
Run Code Online (Sandbox Code Playgroud)

现在你的最后一次调用testAll会给你一个数组作为结果.

const test = (name) => {
    return new Promise(function(resolve, reject) {
        setTimeout(_ => { // Introduce delay for better demo
            console.log('.'); // a little trace in the output
            resolve(name); 
        }, 500);
    });
};

const testAll = (arr) => {
  let functions = arr.map(element => test.bind(null, element));
  return functions.reduce((prom, fun) => 
      prom.then(data => Promise.all(data.concat(fun())) ),
      Promise.resolve([])
  );
}

const arr = ['promise1', 'promise2', 'promise3'];

testAll(arr).then(data => console.log(data));
Run Code Online (Sandbox Code Playgroud)