在节点中使用promise来循环返回相同的响应

当使用q时,我得到相同的响应循环次数:

function start() { var the_promises = []; var api_info = config.AFV var deferred = Q.defer(); var extPath = '/search/' var callType = 'GET' var mymd = buildmd5(api_info, extPath, callType); for(var page=1;page<4;page++) { console.log('getting page:'+page) new Client().get(url'+page, function(data, response){ deferred.resolve(data); }); the_promises.push(deferred.promise); } return Q.all(the_promises); } start().then(function (clips) { inspect(clips) }); 

输出:resultPageNumber:['1'],resultPageNumber:['1'],resultPageNumber:['1'],resultPageNumber:['1'],

我觉得我可能有var deferred = Q.defer(); 在错误的地方,它保留了不同的承诺。 我知道这个版本的代码不是function,但我只关心承诺。 谢谢!

您需要为每个新的客户端创build一个新的延迟。 并在立即调用的函数中折腾这个循环体,以适当地确定var的范围。

 function start() { var the_promises = []; var api_info = config.AFV; var extPath = '/search/'; var callType = 'GET'; var mymd = buildmd5(api_info, extPath, callType); for(var page=1;page<4;page++) { (function() { var deferred = Q.defer(); console.log('getting page:'+page); new Client().get('url'+page, function(data, response){ deferred.resolve(data); }); the_promises.push(deferred.promise); }()); } return Q.all(the_promises); } start().then(function (clips) { inspect(clips); }); 

我不喜欢现有的解决scheme,这是有风险的。 如果承诺错误会发生什么? 如果在代码中有另一个问题,会发生什么?

我的build议是始终把可能的最低原始数字化

在我们的情况下。 我会承诺Client.get方法。

 Client.prototype.getAsync = function(url){ var d = Q.defer(); // or better, using Q.Promise( // please also consider adding a d.reject on the error case. this.get(url, function(data){ d.resolve(data); }); return d.promise; } 

这个新的api会让你做:

 var promises = [1,2,3,4].map(function(page){ return new Client().getAsync("url"+page); }); return Q.all(promises); 

然后获得丹的答案类似的API。 这在我看来好多了,而且很less出错。