将产生的过程中的数据保存到Javascript中的变量中 [英] Saving data from spawned process into variables in Javascript

查看:39
本文介绍了将产生的过程中的数据保存到Javascript中的变量中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在从生成的python进程保存结果时遇到问题.将数据转换为json之后,我将在调用生成程序之前将数据推送到函数内定义的数组中,但是该数组始终返回未定义状态.我可以console.log并正确显示数据,但是从函数返回的数组是未定义的.任何投入将不胜感激.预先感谢.

I am having issues saving the results from a spawned python process. After converting data into json, I push the data to an array defined within the function before the spawn process is called, but the array keeps returning undefined. I can console.log and show the data correctly, but the array that is returned from the function is undefined. Any input would be greatly appreciated. Thanks in advance.

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文档,

First of all, going through the NodeJS documentation, we have

  1. 子进程
  2. [child_process.spawn(command ,args] [,选项])
  3. 子流程类
  4. 流可读事件数据"

即使 projects_py.stdout.on(event_name,callback)接受回调,它仍会返回类似 EventEmitter 的对象,并在其中注册事件(在此示例中)情况下,调用方法 on stdout parent 元素(名为 ChildProcess projects_py ).

Even though projects_py.stdout.on(event_name, callback) accepts an callback, it returns either the EventEmitter-like object, where the events are registered (in this case, stdout that had it's method on called), or the parent element (the ChildProcess named projects_py).

这是因为每次发生"data" 事件时都会调用 callback 函数.因此,如果事件的分配返回的结果与 callback 函数相同,则它将仅返回一次,然后每发生一次"data" 事件将由函数处理,但不会完成.

It's because the callback function will be called every time the "data" event occurs. So, if the assign of the event returned the same as the callback function, it'd return only one single time, and then every next happening of the "data" event would be processed by the function, but not would be done.

在这种情况下,我们需要一种在完成后收集并编译 projects_py.stdout.on("data",callback)事件的数据的方法.您已经有了收集部分.现在查看其他:

In this kind of situation, we need a way to collect and compile the data of the projects_py.stdout.on("data", callback) event after it's done. You already have the collecting part. Now see the other:

在创建on "data" 事件之前,我们创建了一个封装过程的承诺:

Right before you create the on "data" event, we create a promise to encapsulate the process:

    // 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));
}

现在,如果您想对一系列项目进行任何操作,则有两个主要选项:

Now, if you want to do anything with your array of projects, there are two main options:

// 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 中(然后使用/catch和回调)对它进行promise-things.

Also, you can just return the promise variable and do the promise-things with it out of sonar_projects (with then / catch and callbacks).

// 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
    ...
}

这篇关于将产生的过程中的数据保存到Javascript中的变量中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆