简体   繁体   English

将生成的进程中的数据保存到 Javascript 中的变量中

[英]Saving data from spawned process into variables in Javascript

I am having issues saving the results from a spawned python process.我在保存生成的 python 进程的结果时遇到问题。 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.将数据转换为 json 后,我在调用生成过程之前将数据推送到 function 中定义的数组,但数组一直返回未定义。 I can console.log and show the data correctly, but the array that is returned from the function is undefined.我可以 console.log 并正确显示数据,但是从 function 返回的数组是未定义的。 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;
    });  
}

First of all, going through the NodeJS documentation, we have首先,通过 NodeJS 文档,我们有

  1. Child Process子进程
  2. [child_process.spawn(command , args][, options]) [child_process.spawn(command , args][, options])
  3. Child Process Class 子进程 Class
  4. Stream Stream
  5. Stream Readable Event "data" Stream 可读事件“数据”

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 ).即使projects_py.stdout.on(event_name, callback)接受回调,它也会返回EventEmitter -like object,其中注册了事件(在这种情况下, stdout调用on它的方法),或者parent元素( ChildProcess名为projects_py )。

It's because the callback function will be called every time the "data" event occurs.这是因为每次"data"事件发生时都会调用callback function。 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.因此,如果事件的分配返回与callback function 相同,它只会返回一次,然后每次发生"data"事件都会由 function 处理,但不会完成。

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.在这种情况下,我们需要一种方法来收集和编译projects_py.stdout.on("data", callback)事件完成后的数据。 You already have the collecting part.你已经有了收集部分。 Now see the other:现在看另一个:

Right before you create the on "data" event, we create a promise to encapsulate the process:在您创建 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));
}

Now, if you want to do anything with your array of projects, there are two main options:现在,如果您想对您的一系列项目做任何事情,有两个主要选项:

Promise (then / catch) way Promise(接/接)方式

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

Also, you can just return the promise variable and do the promise-things with it out of sonar_projects (with then / catch and callbacks).此外,您可以只返回promise变量,并在sonar_projects中使用它(使用 then / catch 和回调)做承诺。

async / await way异步/等待方式

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM