我需要发出请求以获取html列表,并且需要对其进行扫描并遍历它,并对找到的列表中的每个项目进行更多的请求,其中可能包含列表,依此类推,直到没有列表为止。 。
我需要一种方法来跟踪所有已调用的请求,并在完成后调用另一个函数。棘手的是,该函数为HTML中找到的所有列表项反复调用自身。
我遇到的问题是使用Q Promises,它等待的唯一Promises是来自第一个请求,我不明白为什么假设节点的工作方式与我认为的一样,请参见代码:
var _ = require('underscore');
var request = require('request');
var allPromises = [];
var finalArray = [];
var start = function(id) {
var deferred = Q.defer();
request.get({
url: 'http://www.example.com/id/' + id
}, function() {
_.each(body.items, function(index) {
var item = this;
finalArray.push(item);
if(item.hasMore) {
start(item.id);
}
}
deferred.resolve();
});
allPromises.push(deferred.promise);
}
console.log('Starting');
start(1);
Q.all(allPromises).done(function (values) {
console.log('All Done');
});
我以为发生了什么事:
1-首次调用starts()并创建第一个延迟的var
2-发出第一个请求,并将第一个创建的延迟的变量推入promises数组
3-Q.all被调用并等待
4-第一个请求的回调称为5-如果请求包含body.x,则使用新的ID再次调用start()
6-创建并推送新的Promise,并提出新的请求
7-解决第一个Promise
假设这只深入了一个层次
8-第二个承诺已解决
9-Q.all调用其回调
但是实际上,Q.all在第一个承诺之后调用其回调,即使第二个承诺在第一个承诺解决之前就被推送,它也不会等待其他任何回调。
为什么?我该如何进行这项工作?
更新忘记将循环添加到请求回调中。
对已编辑问题的答案:
var request = require('request');
var finalArray = [];
var start = function(id) {
var deferred = Q.defer();
request.get({
url: 'http://www.example.com/id/' + id
}, function() {
var subitems = [];
_.each(body.items, function(index) {
var item = this;
finalArray.push(item);
if(item.hasMore) {
subitems.push(start(item.id));
}
}
if (subitems.length) {
deferred.resolve(Q.all(subitems)); // resolve result of Q.all
} else {
deferred.resolve();
}
});
return deferred.promise;
}
start(1).done(function() {
console.log('All Done');
});
@Bergi的代码
var request = require('request');
var start = function(id) {
var deferred = Q.defer();
request.get({
url: 'http://www.example.com/id/' + id
}, function(err, body) {
if (err) deferred.reject(err);
else deferred.resolve(body);
});
return deferred.promise.then(function(body) {
var finalArray = [];
return Q.all(_.map(body.items, function(index) {
var item = this;
finalArray.push(item);
if(item.hasMore)
return start(item.id);
else
return [];
})).then(function(moreResults) {
return finalArray.concat.apply(finalArray, moreResults);
});
});
}
start(1).then(function(finalArray) {
console.log('All Done');
});
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句