控制异步循环

时间:2016-10-04 18:42:13

标签: javascript node.js mongodb express

我有两个不同的Node.js程序。

一个是Express.js服务器(PROGRAM1),它提供用户界面和RESTful API。

另一个是爬虫(PROGRAM2),它继续阅读项目,从网上下载并将所有内容存储到数据库中。顺便说一句,我使用Array.prototype.reduce()Promise来迭代文件并逐个处理I / O.

我想在这里做的一件事是监控和控制来自PROGRAM2的抓取工具(PROGRAM1)的进度。

但我发现它非常复杂。

// Control the loop by this `flag`, the value can be assigned from outside
var flag = "IDLE"; 
// The outside can read this `index`, and monitor the progress
var current_index = -1;
var PAGE_SIZE = 100;
function handleBatch(index){
   var defer = q.defer();
   // Mongoose statement to find documents...
   Book.find()
       .skip(index*PAGE_SIZE).limit(PAGE_SIZE).then(function(books){
           var finished = 0;
           for(var i=0; i<books.length; i++){
              var book = books[i];
              downloadInfo(book).then(function(bookInfo){
                  if(flag === "STOP")
                      defer.reject(new Error("The loop should stop!"));
                  //store the info...
                  finished ++;
                  if(finished === PAGE_SIZE)
                     defer.resolve();
              });
           }
       });
    return defer.promise;
}

var promiseHandler;
function main(){
   while(true){
       if(flag === "IDLE")
         continue;
       else if(flag === "START"){
          var [0,1,2,3,4,5...,2500].reduce(function(lastPromise, nextIndex){
             promiseHandler = lastPromise.then(function(){
                 currentIndex = nextIndex;
             });
          }, q());
       }else if(flag === "STOP"){
             promiseHandler.then(null, function(err){
                 flag = "IDLE";                     
             });
       }
   }      
}

main()只是一个例子(例如。实际上它是一个服务器,状态可以通过PROGRAM1的请求更改)。通过将flag设置为STOPhandleBatch()中的循环将发现更改并抛出Exception,然后程序将暂停。

但是,我只是不喜欢这种方式,因为它看起来太丑陋并且通过抛出错误来控制进程。所以我正在寻找一种更好的方法来控制和监控循环。任何一个想法?

2 个答案:

答案 0 :(得分:0)

您应该查看node.js'process的文档。 要回答关于停止执行的问题,请点击此处 - &gt;

  

process.exit(0);

就像一个提示:不要使用循环来控制你的程序。这很糟糕。

答案 1 :(得分:0)

通过它的声音,您正在寻找在节点js中实现进程间通信的方法。这是一个广泛的编程主题,超越了节点js。有很多模式和方法可以实现这一点,但我最喜欢的一个是使用消息队列来松散地耦合这两个过程。

在节点j上,我们有Redisnode-redis之类的东西,可用于实现发布 - 订阅模式。当然,还有许多消息传递库也可以使用。

在您的情况下,Express API可能会发布“暂停”事件,并且抓取工具可以订阅该事件并采取一些措施。然后你的节点应用程序保持异步(不是(真的)废话!)。