问题
I'm trying to run a python script using my javascript file through the child_process.spawn system, but it seems to never run on the aws lambda.
The relevant code is :
getEntities: function (){
var spawn = require('child_process').spawn;
var py = spawn('python', ['mainPythonFile.py']);
var outputString = "starting string";
console.log("BEFORE ANY INPUT");
py.stdout.on('data', function (data) {
console.log("----Getting information from the python script!---");
outputString += data.toString();
console.log(outputString);
});
py.stdout.on('end', function (){
console.log("===hello from the end call in python files===");
console.log("My output : " + outputString);
});
console.log("NO INPUT CHANGED??");
return outputString;
}
These files are in the same level of the folder structure (surface level).
The python file being run is quite simple and only contains a few print statements:
MainPythonFile:
import sys;
print("Hello There");
print("My name is Waffles");
print("Potato Waffles");
sys.stdout.flush()
The output I get from the aws service is this :
BEFORE ANY INPUT
NO INPUT CHANGED??
starting string
I've tried different paths on trying to access the python file, such as
*mainPythonFile.py
./mainPythonFile.py
etc.
I think the code seems to be fine as this works on my local machine, but there's a subtlety of trying to make it run on AWS that I cannot understand.
I can provide any other info if need be.
NOTE: the "getEntities" function is being called by another node.js file, but I moved the code to the calling function, I get the same result.
回答1:
Due to the asynchronous nature of JS, as explained by Chris, the function reaches the "return" statement before the "end" in the spawned thread is actually called.
This means the code never got a chance to actually set the correct output text.
I changed my function calls to take in a callback, that would then respond when the program had replied with the information.
My new function is slightly changed to this (without the prints):
getEntities: function(callbackFunction, that){
var spawn = require('child_process').spawn;
var py = spawn('python', ['mainPythonFile.py']);
var outputString = "starting string";
py.stdout.on('data', function (data) {
outputString += data.toString();
});
// that = "this == alexa" that's passed in as input.
py.stdout.on('end', function (){
callbackFunction(outputString, that);
});
The function that called this function is now as follows :
HelperFunctions.getEntities(function(returnString,that){
that.response.speak(returnString);
that.emit(':responseReady');
}, this);
I'm sure there's a prettier way to do this, but this seems to be working for now. Thanks to ChrisG
来源:https://stackoverflow.com/questions/50826884/using-child-process-spawn-on-aws-lambda-for-a-python-script