Maximum call stack size exceeded in nodejs

2020-05-08 19:22发布

I used events in nodejs to implement my logic. And "nextParams" is an event that make function "extractVideo" executed again. I know I used recursive event loop. I tried to used setTimeout(function, 0) and setTimeout(function, 1) in my code, but the error "Maximum call stack size exceeded" still appear, I wonder does anybody know how to fix this problem, I am appreciated very much!

    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);  
    }

below are functions

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

标签: node.js
1条回答
乱世女痞
2楼-- · 2020-05-08 20:08

For certain problems that involve tail calls, you can turn on the tail call optimization in some versions of Node (since 6.5 but not any more since 8.0!).

See this for compatibility:

For info on proper tail calls, see:

For other cases where you don't have tails calls you should use setImmediate() or process.nextTick() depending on when you want your code to run, instead of using setTimeout() because those are better optimized but setTimeout() would still avoid the call stack from growing. But here you don't use setTimeout() for every call and that is probably the problem.

查看更多
登录 后发表回答