nodejs中超出了最大调用堆栈大小

时间:2017-02-14 06:17:48

标签: node.js

我在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");
      }

1 个答案:

答案 0 :(得分:0)

对于涉及tail calls的某些问题,您可以在某些版本的Node中启用尾调用优化(自6.5以来,但自8.0以来不再有!)。

请参阅此内容以了解兼容性:

有关正确尾调用的信息,请参阅:

对于您没有收到尾调用的其他情况,您应该使用setImmediate()process.nextTick(),具体取决于您希望代码运行的时间,而不是使用setTimeout(),因为这些更好地优化,但setTimeout()仍然可以避免调用堆栈的增长。但是在这里你不会为每次通话使用setTimeout(),这可能就是问题所在。