首先,通过 NodeJS 文档,我们有
- Child Process
- [child_process.spawn(command, args][, options])
- Child Process Class
- Stream
- Stream Readable Event "data"
即使projects_py.stdout.on(event_name, callback) 接受回调,它也会返回类似EventEmitter 的对象,其中注册了事件(在这种情况下,stdout 调用了它的方法on)或@987654330 @ 元素(ChildProcess 名为 projects_py)。
这是因为每次"data"事件发生时都会调用callback函数。因此,如果事件的分配返回与callback 函数相同,它只会返回一次,然后"data" 事件的下一次发生将由该函数处理,但不会完成.
在这种情况下,我们需要一种方法来收集和编译projects_py.stdout.on("data", callback)事件完成后的数据。
你已经有了收集部分。现在看看另一个:
就在您创建 on "data" 事件之前,我们创建了一个封装该过程的承诺:
// A promise says "we promise" to have something in the future,
// but it can end not happening
var promise = new Promise((resolve, reject) => {
// First of all, we collect only the string data
// as things can come in parts
projects_py.stdout.on('data', function(data){
let json = Buffer.from(data).toString()
str += json
});
// When the stream data is all read,
// we say we get what "we promised", and give it to "be resolved"
projects_py.stdout.on("end", () => resolve(str));
// When something bad occurs,
// we say what went wrong
projects_py.stdout.on("error", e => reject(e));
// With every data collected,
// we parse it (it's most your code now)
}).then(str => {
let json2 = str.replace(/'/g, '"')
// I changed obj to arr 'cause it seems to be an array
let arr = JSON.parse(json2)
//console.log(json2)
const projects = []
// With for-of, it's easier to get elements of
// an object / an array / any iterable
for(var dat of arr){
var project = new all_sonar_projects(
dat.key, dat.name, dat.qualifier,
dat.visibility, dat.lastAnalysisDate
);
projects.push(project);
}
// Template strings `a${variable or expression}-/b`
// are easier to compile things into a big string, yet still fast
for(var i = 0; i < projects.length; i++)
console.log(
`${projects[i].key} ${projects[i].name} ` +
`${projects[i].qualifier} ${projects[i].visibility} ` +
projects[i].lastAnalysisDate
)
console.log(projects)
// Your projects array, now full of data
return projects;
// Finally, we catch any error that might have happened,
// and show it on the console
}).catch(e => console.error(e));
}
现在,如果您想对您的一系列项目做任何事情,有两个主要选择:
承诺(then/catch)方式
// Your function
function sonar_projects(){
// The new promise
var promise = ...
// As the working to get the projects array
// is already all set up, you just use it, but in an inner scope
promise.then(projects => {
...
});
}
此外,您可以只返回 promise 变量并使用它在 sonar_projects 之外执行承诺(使用 then / catch 和回调)。
异步 / 等待方式
// First of all, you need to convert your function into an async one:
async function sonar_projects(){
// As before, we get the promise
var promise = ...
// We tell the function to 'wait' for it's data
var projects = await promise;
// Do whatever you would do with the projects array
...
}