2017-02-14 15 views
0

私のロジックを実装するためにnodejsのイベントを使用しました。また、 "nextParams"は、関数 "extractVideo"を再度実行させるイベントです。私は再帰的なイベントループを使用することを知っています。自分のコードでsetTimeout(function、0)とsetTimeout(function、1)を使用しようとしましたが、 "Maximum call stack size exceeded"というエラーが表示されます。 !以下nodejsの最大呼び出しスタックサイズを超えました

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

機能tail callsを伴う特定の問題については

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

ている、あなたはノードの一部のバージョンでは末尾呼び出しの最適化をオンにすることができます。互換性のためにこれを参照してください。適切な末尾再帰の詳細については

、以下を参照してください。あなたが尾を持っていない他の例については

をあなたはあなたが欲しいときに応じてsetImmediate()またはprocess.nextTick()を使用する必要がありますこれらのコードは最適化されているため、setTimeout()を使用するのではなく、呼び出しスタックが増加するのを回避するために、setTimeout()を実行する必要があります。しかしここではすべての呼び出しにsetTimeout()を使用しないでください。これはおそらく問題です。

関連する問題