简体   繁体   中英

Accessing values from blocking Javascript functions in Node

The below function, startScript , contains blocking code that takes some time to run. In my setInterval loop, I want to access the weight value that it returns. However, when I run this Node program I receive an error saying that new_weight is undefined.

I tried running startScript.on('close', ...) within the loop, but this throws an error saying that there is no method on for startScript

What am I doing wrong here?

var spawn = require('child_process').spawn
var path = require('path');
var split = require('split');
var pythonData = [];
var weight = null;

function startScript(){
  var pyScript = spawn('python', [ path.join(__dirname, 'script.py') ]);
  pyScript.stdout.on('data', function(lineChunk){
    pythonData = lineChunk.toString().replace(/[\S|\n|\[|\]]/,"").split(',');
  });

  pyScript.on('close', function(code){
    var sum = 0;
    for(var i=0; i < pythonData.length; i++){
      sum += parseFloat(pythonData[i]);
    }
    var weight = sum / pythonData.length;
    console.log("weight: " + weight);
    return weight;
  });
}

setInterval(function(){
  if (some event that occurs infrequently){
    startScript();
    var new_weight = weight + 100
    console.log(new_weight);
  }
}, 1000);

You cant' return from pyScript.on() , it's asynchronous. The parent function has returned already long before the other return happens. Instead, you must use callbacks.

function startScript(callback){ // ******
  var pyScript = spawn('python', [ path.join(__dirname, 'script.py') ]);
  pyScript.stdout.on('data', function(lineChunk){
    pythonData = lineChunk.toString().replace(/[\S|\n|\[|\]]/,"").split(',');
  });

  pyScript.on('close', function(code){
    var sum = 0;
    for(var i=0; i < pythonData.length; i++){
      sum += parseFloat(pythonData[i]);
    }
    var weight = sum / pythonData.length;
    console.log("weight: " + weight);
    //return weight; // you can't return weight. Instead, execute the callback.
    callback(weight); // ******
  });
}

setInterval(function(){
  if (some event that occurs infrequently){
    startScript(function(weight){ // ******
      var new_weight = weight + 100
      console.log(new_weight);
    }); // ******
  }
}, 1000);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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