如何将累积的返回Promise值作为数组返回到Array.prototype.reduce()之后的.then()?

gue*_*314 -5 javascript arrays promise jquery-deferred

鉴于这种模式

someArray.reduce(function(p, item) {
  return p.then(function() {
    return someFunction(item);
  });
}, $.Deferred().resolve()).then(function() {
  // all done here
  // access accumulated fulfilled , rejected `Promise` values
}, function err() {

});
Run Code Online (Sandbox Code Playgroud)

什么方法可以将已完成的,被拒绝的Promise对象的累积值返回到.then(fulfilled)调用后的数组.reduce()

function someFunction(index) {
  console.log("someFunction called, index = " + index);
  var $deferred = $.Deferred();

  window.setTimeout(function() {
    $deferred.resolve();
  }, 2000);

  return $deferred.promise();
}
   
var someArray = [1,2,3,4,5];

someArray.reduce(function(p, item) {
  return p.then(function() {
    return someFunction(item);
  });
}, $.Deferred().resolve()).then(function(data) {
  // all done here
  console.log(data, arguments) // `undefined` , `[]`
});
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
Run Code Online (Sandbox Code Playgroud)

jfr*_*d00 8

根据您尝试做的具体情况,有多种可能的策略:这是一个选项:

someArray.reduce(function(p, item) {
  return p.then(function(array) {
    return someFunction(item).then(function(val) {
        array.push(val);
        return array;
    });
  });
}, $.Deferred().resolve([])).then(function(array) {
  // all done here
  // accumulated results in array
}, function(err) {
  // err is the error from the rejected promise that stopped the chain of execution
});
Run Code Online (Sandbox Code Playgroud)

工作演示:http://jsfiddle.net/jfriend00/d4q1aaa0/


仅供参考,Bluebird Promise库(我通常使用的).mapSeries()是为此模式构建的:

var someArray = [1,2,3,4];

Promise.mapSeries(someArray, function(item) {
    return someFunction(item);
}).then(function(results) {
    log(results);
});
Run Code Online (Sandbox Code Playgroud)

工作演示:http://jsfiddle.net/jfriend00/7fm3wv7j/