在for循环中进行函数调用同步
我在请求中得到一个string数组。 每个string都包含一个要在本机shell上执行的命令。
var process = require('child_process'); function execCommand(req,res,callback){ var params = req.params.list //list is an array in the request var result = ''; var command = ''; for (var i = 0; i < params.length; i++) { command = params[i]; cmd = process.exec(command); cmd.stdout.on('data', function(data){ //push the shell output in variable result }); cmd.on('close', function(code) { //convert the variable result to a valid JSON }); } res.send(result); };
所有命令的result
混在result
variables中。 如何使for
循环中的函数调用同步?
您可以使用execSync
或…
您需要添加一个控制stream库以帮助进行asynchronous调用,以便您可以select以串行或并行方式运行您的函数:
- asynchronous: https : //www.npmjs.com/package/async
- Q(使用promise,使用
Q.nfcall
) https://www.npmjs.com/package/q
使用execSync而不是exec!
for (var i = 0; i < params.length; i++) { command = params[i]; result += process.execSync(command).toString(); }
正如其他人所指出的,这可能不是一个好主意,因为它会阻止事件循环和正在发生的任何请求。 如果正在执行的进程需要很短的时间才能完成,否则是可以接受的。
下面是一个简单的模式来控制for循环中asynchronous函数的stream程…每当进程返回时, params_finished
都会增加1。 一旦完成的进程数等于响应发送的进程总数。
for (var i = 0, total_params=params.length, params_finished=0; i < total_params; i++) { command = params[i]; cmd = process.exec(command); cmd.stdout.on('data', function(data){ //push the shell output in variable result }); cmd.on('close', function(code) { //convert the variable result to a valid JSON params_finished++ if(params_finished == total_params){ res.send(result); } }); }
另一种方法是在循环内部使用相当于sleep
函数。 如果你知道每个循环实例需要多less时间。
function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function myLoopFunction(){ // any code before loop for (var i = 0; i < params.length; i++) { // do whatever await sleep(3000); // 3000 milisecond, for instance } };
请参阅此答案以获取有关此方法如何工作的完整说明。