观看NodeJS群集退出

时间:2015-01-29 16:20:52

标签: javascript node.js asynchronous

我很难绕过一个node.js进程(异步的)运行但仍然触发'退出'状态,所以当CPU运算完成时我可以做更多。

例如,我有一个Google Places抓取工具,可以在所有可用的CPU上有效地分发http请求。

} else if (cluster.isWorker) {
//  Code to run if we're in a worker process

// Send the object we created above from variables so they're available to the workers
process.on('message', function(clusterDivisionObject) {
    var tempArray;

    // Send the chunk of array appropriate for this cluster to process, then request it's place details
    tempArray = clusterDivisionObject.placeIdArray.splice(((cluster.worker.id * clusterDivisionObject.clusterDivision) - clusterDivisionObject.clusterDivision), clusterDivisionObject.clusterDivision);
    tempArray.forEach(function(arrayItem, index, array){
      request({url: config.detailsRequestURI + '?key=' + config.apiKey + '&placeid=' + arrayItem, headers: config.headers}, detailsRequest);
    });
});
}

这里的真正问题是我发送异步request()语句的最后一行。代码执行正确,但是一旦我点击回调(detailsRequest)做某事(在这种情况下,写入json文件)我没有任何控制退出进程。我的回调函数:

function detailsRequest(error, response, body) {
    if (!error && response.statusCode == 200) {
        var detailsBody = JSON.parse(body);
        ...
    }
}

...无法了解正在运行的进程或进行了多少次迭代(在整个tempArray耗尽后触发退出)。因此,假设一个群集的request()长度为tempArray x长度,那么当process.exit(0)完成后如何触发tempArray.forEach(){}

我已尝试在tempArray.forEach(){}之后直接调用process.exit(0),但该进程将在request()运行之前死亡。 有没有什么有效的方法我可以更好地观看流程以调用它的退出,或者我真的试图解决一个不存在的问题,因为request()是异步的,可以按任何顺序调用或不调用吗

1 个答案:

答案 0 :(得分:1)

您需要异步流量控制。在所有请求完成之前,您不希望您的流程退出。相反,您要求节点发送所有这些请求,然后退出该过程。结帐async.js或其他一些流量控制库。但是你需要这样的东西:

var tempArray;
var counter = 0;

tempArray = []; // same as above

// Without asyncjs
tempArray.forEach(function(arrayItem, index, array){
  request({url: config.detailsRequestURI + '?key=' + config.apiKey +'&placeid=' + arrayItem, headers: config.headers}, detailsRequest);
});

function detailsRequest(){ 
 // increment counter and handle response
 // this callback gets called N times.
 counter +=1;
 if(counter >= tempArray.length){ process.exit(0); }
}


//With async.js:

async.map(tempArray, sendRequestFunc, function finalDone(err, results){ 
  // here you can check results array which has response
  // and then exit
  process.exit(0);
}); 

function sendRequestFunc(el, done){ 
  // done callback as per async docs
  // done must be invoked here or the final callback is never triggered 
  request({url:'same as above'}, done)
}

请注意,您可能需要为错误或错误响应添加其他检查,并相应地处理这些错误。

sendRequestFunc中的完成回调仅在请求返回响应或错误(异步)以及最后一次异步回调' finalDone'时调用。仅在返回所有响应时调用。