保存派生python进程的结果时遇到问题。将数据转换为json后,在调用spawn进程之前,我将数据推送到函数中定义的数组中,但该数组始终返回未定义的数据。我可以安慰你。正确记录并显示数据,但函数返回的数组未定义。如有任何意见,将不胜感激。提前谢谢。
function sonar_projects(){
const projects = [];
let obj;
let str = '';
const projects_py = spawn('python', ['sonar.py', 'projects']);
let test = projects_py.stdout.on('data', function(data){
let projects = [];
let json = Buffer.from(data).toString()
str += json
let json2 = json.replace(/'/g, '"')
obj = JSON.parse(json2)
console.log(json2)
for(var dat in obj){
var project = new all_sonar_projects(obj[dat].key, obj[dat].name, obj[dat].qualifier, obj[dat].visibility, obj[dat].lastAnalysisDate);
projects.push(project);
}
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)
return projects;
});
}
首先,通过查阅NodeJS文档,我们有
即使projects_py.stdout.on(event_name,回调)
接受回调,它也会返回类EventEmitter的对象,其中注册了事件(在本例中,stdout
具有它的方法on
调用),或父
元素(名为ChildProcess
的projects_py
)。
这是因为每次发生“data”
事件时都会调用回调
函数。因此,如果事件的赋值返回的与回调
函数相同,那么它只会返回一次,然后“data”
事件的下一次发生都会由函数处理,但不会执行。
在这种情况下,我们需要一种方法来收集和编译projects_py.stdout.on(data,回调)
事件完成后的数据。你已经有了收集部分。现在看看另一个:
在创建on“data”
事件之前,我们promise封装流程:
// 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));
}
现在,如果您想对项目阵列执行任何操作,有两个主要选项:
// 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
之外执行promise的事情(然后使用/cat和回调)。
// 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
...
}