一尘不染

如何按顺序在Q中链接可变数量的Promise?

node.js

我已经看到在Q中链接任意数量的诺言;我的问题是不同的。

如何进行可变数量的调用,每个调用均按顺序异步返回?
该方案是一组HTTP请求,其数量和类型由第一个HTTP请求的结果确定。

我想简单地做到这一点。

我也看到了这个答案,暗示着这样的事情:

var q = require('q'),
    itemsToProcess =  ["one", "two", "three", "four", "five"];

function getDeferredResult(prevResult) {
  return (function (someResult) {
    var deferred = q.defer();
    // any async function (setTimeout for now will do, $.ajax() later)
    setTimeout(function () {
      var nextResult = (someResult || "Initial_Blank_Value ") + ".." + itemsToProcess[0];
      itemsToProcess = itemsToProcess.splice(1);
      console.log("tick", nextResult, "Array:", itemsToProcess);
      deferred.resolve(nextResult);
    }, 600);

    return deferred.promise;
  }(prevResult));
}

var chain = q.resolve("start");
for (var i = itemsToProcess.length; i > 0; i--) {
    chain = chain.then(getDeferredResult);
}

…但是以这种方式遍历itemsToProcess似乎很尴尬。或定义一个称为“循环”的新函数来抽象递归。有什么更好的方法?


阅读 341

收藏
2020-07-07

共1个答案

一尘不染

使用可以很好地解决这一问题[].reduce

var chain = itemsToProcess.reduce(function (previous, item) {
    return previous.then(function (previousValue) {
        // do what you want with previous value
        // return your async operation
        return Q.delay(100);
    })
}, Q.resolve(/* set the first "previousValue" here */));

chain.then(function (lastResult) {
    // ...
});

reduce遍历数组,传入上一次迭代的返回值。在这种情况下,您将返回诺言,因此每次您链接一个then。您提供了一个初始承诺(如您所做的那样q.resolve("start"))以开始工作。

刚开始时,可​​能需要花一些时间来思考这里发生的事情,但是如果您花一点时间来解决它,那么在任何地方使用它都是一种简单的模式,而无需设置任何机械。

2020-07-07