我已经看到在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似乎很尴尬。或定义一个称为“循环”的新函数来抽象递归。有什么更好的方法?
使用可以很好地解决这一问题[].reduce。
[].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"))以开始工作。
reduce
then
q.resolve("start")
刚开始时,可能需要花一些时间来思考这里发生的事情,但是如果您花一点时间来解决它,那么在任何地方使用它都是一种简单的模式,而无需设置任何机械。