nodejs Q.all承诺函数调用本身
nodejs Q.all promises on function calling itself
我需要发出一个请求来获取html列表,我需要扫描它并循环浏览它,并为找到的列表中的每一项发出更多请求,这些请求中可能有列表,依此类推,直到没有列表为止。
我需要一种方法来跟踪所有调用的请求,并在它们完成后调用另一个函数。棘手的是,对于HTML中的任何列表项,函数都会一遍又一遍地调用自己。
我遇到的问题是使用Q promise,它唯一等待的promise来自第一个请求,我不明白为什么假设节点像我认为的那样工作,请参阅代码:
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-发出第一个请求,并将第一个创建的延迟变量推送到promise数组
3-Q.all被调用并等待
4-调用第一个请求的回调5-如果请求包含body.x,则使用新id再次调用start()
6-创建并推送新的promise,并提出新的请求
7-第一个承诺被解决
假设这只深入一级
8-第二个承诺得到解决
9-Q.all调用其回调
但在实践中,Q.all在第一个promise之后调用回调,即使在第一个promise被解析之前推送了第二个promise,它也不会等待任何其他promise。
为什么?我该怎么做?
Update忘记在请求回调中添加循环。
编辑问题的答案:
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');
});
相关文章:
- 是否可以将一个函数输入连接到另一个函数调用的文本
- 在输入字段上有两个函数调用,一个在Blur上,一个不在Angular中
- 如何在Javascript函数调用中循环变量
- Javascript:应为赋值或函数调用,但实际看到的却是表达式
- 如何远程检查JavaScript应用程序的函数调用堆栈
- javascript函数调用不起作用
- 为什么这个函数调用会破坏程序并导致未定义的变量
- 如何通过函数调用设置图像的src
- 从全局函数调用Ember控制器上的方法
- 为什么Jquery$.ajax在函数调用中触发所有statusCode,即使调用成功
- 按照承诺,通过与chai的函数调用验证已解析承诺的内容
- 承诺与函数调用/设置超时
- 可以 Angular 模板调用函数返回承诺
- 如何递归调用承诺函数
- 测试使用摩卡在其中调用承诺的函数
- Node sequelize回调承诺期望一个函数,是否有一种方法可以通过函数调用删除已声明的函数
- nodejs Q.all承诺函数调用本身
- 承诺加入添加新的函数调用链
- 控制器中的Angular函数在承诺之后没有被调用
- 在承诺内断言函数调用