Run NodeJS event loop / wait for child process to finish

前端 未结 4 1030
暖寄归人
暖寄归人 2021-02-04 11:01

I first tried a general description of the problem, then some more detail why the usual approaches don\'t work. If you would like to read these abstracted explanations go on

4条回答
  •  借酒劲吻你
    2021-02-04 11:27

    What you are running into is a very common scenario that skilled programmers who are starting with nodejs often struggle with.

    You're correct. You can't do this the way you are attempting (loop).

    The main process in node.js is single threaded and you are blocking the event loop.

    The simplest way to resolve this is something like:

    function getImportantData() {
        if(importantData === undefined){ // not set yet
            setImmediate(getImportantData); // try again on the next event loop cycle
            return; //stop this attempt
        }
    
        if (importantData === null) {
            throw new Error("Data could not be generated.");
        } else {
            // we should have a proper data now
            return importantData;
        }
    }
    

    What we are doing, is that the function is re-attempting to process the data on the next iteration of the event loop using setImmediate.

    This introduces a new problem though, your function returns a value. Since it will not be ready, the value you are returning is undefined. So you have to code reactively. You need to tell your code what to do when the data arrives.

    This is typically done in node with a callback

    function getImportantData(err,whenDone) {
        if(importantData === undefined){ // not set yet
            setImmediate(getImportantData.bind(null,whenDone)); // try again on the next event loop cycle
            return; //stop this attempt
        }
    
        if (importantData === null) {
            err("Data could not be generated.");
        } else {
            // we should have a proper data now
            whenDone(importantData);
        }
    }
    

    This can be used in the following way

    getImportantData(function(err){
        throw new Error(err); // error handling function callback
    }, function(data){ //this is whenDone in our case
        //perform actions on the important data
    })
    

提交回复
热议问题