例如:
如果在http.request
回调中进行了res.on('end')
调用,那么该呼叫是递归的吗?
http.request(options, function(res) {
res.on('data', function(chunk) {
data+=chunk;
});
res.on('end', function(){
//do some stuff
http.request(options, function(res) {...});//is this recursive?
});
}).end();
编辑:
让我们举一个更简单的例子:假设有一个函数可以逐个字符地读取文件:
var noOfChar = 10;
var i = 0;
readChar(function processChar(char){
if(i < noOfChar) {
console.log(char);
i++;
readChar(processChar); //is this recursive?
}
}
答案 0 :(得分:2)
让我们考虑一下代码的一些具体属性,以及它与人们通常所说的“递归”的相似或不同之处,而不是争论它的标签。
通常,递归函数会在每一步增加堆栈(尾部调用递归除外,它使用一种技巧来阻止增长)。但是在节点中,异步回调会丢弃外部上下文的堆栈。 (尝试在回调中引发异常并自己查看。)因此,此代码不会增加堆栈。
通常,递归函数也会调用自身,但我不会在您的示例中看到任何地方发生这种情况。 http
上的两个听众是不同的功能。
第二个例子不是直接调用自己,而是间接调用自己。你有一个“基本案例”(noOfChar >= 10
),此时递归会展开。如果readChar
是同步的,你甚至会增加堆栈。所以这似乎更接近递归。
请注意,在第二个示例中,您有一个命名函数,而第一个示例只有匿名函数。一般来说,如果没有命名函数(或者至少是一些保存函数的变量),我不认为递归是可能的,因为否则函数如何引用自身?
答案 1 :(得分:0)
如果您要将不同的callback
传递给它,我认为它不会递归。
如果你将同一个callback
传递给它们,它将是递归的。
递归表示我是否在函数定义中调用相同的函数。但是如果你打算通过不同的回调,它将会像波纹管那样。
假设您有2个不同的回调callback1 and callback2
。
您已将第一个回调传递给外部http.request
,并将第二个回调传递给内部http.request
,因此外部http.request
将执行callback1
中给出的代码,但内部将是执行callback2
中给出的代码。
答案 2 :(得分:0)
我不明白问题的含义 如果答案是肯定的,你会被老板鞭打致死吗? 是否有针对递归的法律?
http.request
只是达到目的的手段。无论如何,您需要多次调用它来处理交易
您的示例代码的问题在于您在一大块代码中处理异步交换,它直接处理响应而不跟踪事务的状态。
我想到的唯一评论是这种逻辑非常脆弱,因为终止条件取决于传递给您的请求的任何参数,从而使大门敞开,导致一些潜在的问题,例如不同步答案和无限循环(他们是否应该得到&#34;递归调用&#34的名称;如果他们最终挂起系统则没什么兴趣。)
我宁愿建议构建一个显式状态机来跟踪预期的HTTP交换的进度,这将解决关于递归性和相关的“良好实践”的哲学问题。
答案 3 :(得分:0)
我会尝试回答我自己的问题,因为我觉得现在我更了解递归。也许这会帮助别人。
我怀疑是否一个函数调用一个回调函数,该函数再次调用该函数,它将被称为递归。我觉得它类似于indirect recursion,其中function1调用function2而function2再次调用function1。因此,如果function1调用function2调用function3,而function3又调用function1,它仍然是递归的,这并不重要。同样,如果函数调用一个调用该调用该函数的另一个回调的回调,则不应该这么重要。如果第二个例子是递归的,那么首先也可以是递归的。
问题的递归解决方案必须解决问题的解决方法,而不是像堆栈增长这样的语言实现。考虑tail-recursion
,它不会增加调用堆栈,但没有人质疑它的递归。
所以关键是要递归思考。解决整个问题,如果其中一部分可以像原始问题一样解决,那么解决方案就是递归。调用自身的函数可能不符合递归的条件。有些人可能称之为自引用函数但不是递归函数。
递归至少应该包含一个基本情况和一个递归的情况,每个自引用应该使输入值更接近基本情况,这将结束递归。所以我认为提到的两个例子问题不是递归的。
递归调用可能不会导致调用堆栈增加。有一个尾调用递归,它使调用堆栈大小保持不变。
采用以下由回调组成的示例,此处外部函数堆栈帧可能在内存中,也可能不在内存中。
var input = [[1,2,3],[4,5,6],[7,8,9]];
function double(ip) {
return ip.map(function (element) {
if(Array.isArray(element)) {
return double(element);
}
else {
return 2 * element;
}
});
}
console.log(double(input));
我称之为递归。我们也可以执行Anonymous Recursion,因此无需明确命名函数。