保持生成过程中的 Node.js 结果有序

Posted

技术标签:

【中文标题】保持生成过程中的 Node.js 结果有序【英文标题】:Keeping Node.js results from spawn process in order 【发布时间】:2014-02-05 15:46:15 【问题描述】:

我最近一直在使用 Node.js,但在寻找一种方法来跟踪子进程 stdout 的结果返回请求时遇到了问题。

我有一个文件中的主机名列表,我的应用程序读取文件,使用简单的正则表达式从文件中一次提取一行主机名,使用拆分。然后我创建一个主机名数组。然后为数组中的每个主机名构建一个参数字符串,并使用该参数字符串生成一个进程,但是,我无法从进程内部访问计数变量“i”,也找不到跟踪结果返回输入。

我的程序应该获取每个主机名并使用“子进程”调用 snmp,然后它应该创建 hostname : "snmp-result" 的数组,最后完成后,将数组保存到文件中。

我正在使用此程序尝试从网络设备中提取序列号。我已经重写了这段代码大约 5 次,我什至尝试使用嵌套在 spawn 进程中的函数而不是 on data 事件发射器,但是我不知所措。相关代码如下:

var spawn = require('child_process').exec;
var split = require('split');
var fs = require('fs');
var snRe = '"(.*?)"';
var devRe = "(junos\\-([a-z]|[0-9])+\\-([a-z]|[0-9])+$)";
var devices = [];
var output = [];
var outfile = fs.createWriteStream('vri.txt','flags':'w');
var infile = fs.createReadStream('devices',flags: 'r', encoding: 'utf8')
var spawnCmd = "/usr/local/bin/snmpwalk -v2c -c public"
var oid = ".1.3.6.1.4.1.2636.3.1.3"

function getSerial(callback) 

    for (var i=0;i<devices.length;i++) 
            var argument = spawnCmd + " " + devices[i] + " " + oid;
            ps = spawn(argument);
            ps.stdout.on('data',function(buf) 
                    if (buf) 
                            output.push(devices[i] + ": " + (buf.match(snRe))[1] +"\n");
                    
                    else 
                    output.push('could not be reached');
                    
                    )
                    //console.log(i + devices[i] + ": " + output[i] + '\n');
            
    
callback();


getDevices(function() 
    getSerial(function() 
            for (var i=0;i<output.length;i++) 
    outfile.write(output[i]);


    )
)

【问题讨论】:

【参考方案1】:

由于 spawn 进程的异步特性,您不能使用 for 循环来处理这样的程序。递归是你的朋友。

var spawn = require('child_process').exec;
var max = 3;

function genSerial(bufs, callback) 
  if(bufs.length === max) 
    callback(null, bufs);
    return;
  
  var ps = spawn('sleep 1; date');
  ps.stdout.on('data',function(buf) 
    console.log(buf);
    bufs.push(buf);
    genSerial(bufs, callback);
  );


genSerial([], function(err, bufs) 
  console.log('showing buffers', bufs);
);

输出是

benny@benny-VirtualBox:~/Documents/so$ node test.js 
Fri Jan 17 06:54:58 NZDT 2014

Fri Jan 17 06:54:59 NZDT 2014

Fri Jan 17 06:55:00 NZDT 2014

showing buffers [ 'Fri Jan 17 06:54:58 NZDT 2014\n',
  'Fri Jan 17 06:54:59 NZDT 2014\n',
  'Fri Jan 17 06:55:00 NZDT 2014\n' ]

【讨论】:

老实说,我从来没有想过这样做。 Node 确实是我第一次深入研究异步编程。看着你的解决方案,灯刚刚熄灭。这是其中一个时刻,不仅我的问题得到了回答,而且你开始思考这将如何彻底改变我看待问题的方式。 很高兴为您提供帮助。要更习惯异步编程,您可以查看slideshare.net/cacois/nodejs-patterns-for-discerning-developers 或其他类似的东西 谢谢,我会检查一下。

以上是关于保持生成过程中的 Node.js 结果有序的主要内容,如果未能解决你的问题,请参考以下文章

在 node.js 中使用参数生成过程

如何在 Node.JS 中获取生成的 child_process 的输出?

Node.js 探秘 - 求异存同

接口测试过程中如何快速进行 diff 测试?

MySQL 结果来自 html 中的 node.js,由 react.js

最常用的生成 PDF 报告的方法(JavaScript、node.js)?