我在nodejs中使用事件来实现我的逻辑。并且“nextParams”是使“extractVideo”功能再次执行的事件。我知道我使用了递归事件循环。我试图在我的代码中使用setTimeout(函数,0)和setTimeout(函数,1),但错误“超出最大调用堆栈大小”仍然出现,我想知道有没有人知道如何解决这个问题,我非常感激!
videoCrawler.prototype.extractVideo=function(queryStr){
self.on("videoIdArray",function(){
if(videoIdArray.length){
self.getVideoInfo(videoIdArray.pop());
}else{
self.videomonitor.emit("nextParams");
}
});
self.on("getVideoIdArray",function(videoidarray){
if(!(videoidarray || videoidarray.length)){
self.videomonitor.emit("nextParams");
}
videoIdArray=videoidarray;
self.getVideoInfo(videoIdArray.pop());
});
self.on("save",function(videodetailinfo){
if(!videodetailinfo){
if(videoIdArray.length){
self.getVideoInfo(videoIdArray.pop());
}else{
self.videomonitor.emit("nextParams");
}
}
self.saveVideoInfo(videodetailinfo);
});
self.on("errorCapture",function(errInfo){
if(errInfo.message=="queryStr is not exits"){
setTimeout(self.videomonitor.emit("nextParams"),1);
}else if(errInfo.message=="videodetailsinfo is not exits"){
self.getVideoInfo(videoIdArray.pop());
}else if(errInfo.message=="videoId is empty"){
self.getVideoInfo(videoIdArray.pop());
}else if(errInfo.message=="save fails"){
self.getVideoInfo(videoIdArray.pop());
}
});
self.getVideoId(queryStr);
}
以下是功能
videoCrawler.prototype.getVideoId=function(queryStr){
if(!queryStr) this.emit("errorCapture",errInfo);
//dosomething
this.emit("getVideoIdArray",videoArray);
}
videoCrawler.prototype.getVideoInfo=function(videoId){
if(!queryStr) this.emit("errorCapture",errInfo);
//dosomething
self.emit("save",videodetails);
}
videoCrawler.prototype.saveVideoInfo=function(videodetailsinfo){
if(!queryStr) this.emit("errorCapture",errInfo);
//dosomething
self.emit("videoIdArray");
}
答案 0 :(得分:0)
对于涉及tail calls的某些问题,您可以在某些版本的Node中启用尾调用优化(自6.5以来,但自8.0以来不再有!)。
请参阅此内容以了解兼容性:
有关正确尾调用的信息,请参阅:
对于您没有收到尾调用的其他情况,您应该使用setImmediate()
或process.nextTick()
,具体取决于您希望代码运行的时间,而不是使用setTimeout()
,因为这些更好地优化,但setTimeout()
仍然可以避免调用堆栈的增长。但是在这里你不会为每次通话使用setTimeout()
,这可能就是问题所在。