Вызов python скрипта в node.js
Имеется два скрипта на Node.js и на python. Пытаюсь, чтобы python-скрипт вызывался у меня в js-скрипте и присылал мне json, но моя функция в js возвращает пустой массив. Что надо исправить?
И второе, как в js-скрипте мне сделать так, чтобы он засыпал допустим на 3 секунды (т.е. нужен аналог time.sleep(3) в python).
Скрипт на nodejs:
function draw() {
const spawn = require("child_process").spawn;
const pythonProcess = spawn('python', ["./generationData.py"]);
let lst = [];
pythonProcess.stdout.on('data', data => {
var myStr = data.toString();
var obj = JSON.parse(myStr);
lst.push(obj);
});
return lst;
};
console.log(draw());
Скрипт на python:
from datetime import datetime
import time
import math
import json
def get_data(step):
id_val = 'prop.fuel'
x = int(str(datetime.now().timestamp()).replace('.', ''))
y = math.sin(step*math.pi/180)
data = {
'timestamp': x,
'value': y,
'id': id_val
}
return json.dumps(data)
if __name__ == '__main__':
print(get_data(5))
Ответы (1 шт):
Автор решения: nörbörnën
→ Ссылка
Причина такого поведения в том, что lst возвращается после объявления обработчиков событий, а не после того как эти обработчики были вызваны.
Есть 2 эффективных способа решить задачу: Promise и callback.
const { spawn } = require('child_process');
(async () => {
try {
const lst = await drawAsync();
console.log('async:', lst);
} catch (err) {
console.error('async error:', err);
}
})();
drawCallback(([err, lst]) => {
if (err) {
console.error('cb error:', err);
}
console.log('cb:', lst);
});
async function drawAsync() {
return new Promise((resolve, reject) => {
const pythonProcess = spawn('python3', ["./generationData.py"]);
let lst = [];
pythonProcess.stdout.on('data', data => {
var myStr = data.toString();
var obj = JSON.parse(myStr);
lst.push(obj);
});
pythonProcess.on('close', (code) => resolve(lst));
pythonProcess.on('error', (err) => reject(err));
});
}
function drawCallback(cb) {
const pythonProcess = spawn('python3', ["./generationData.py"]);
let lst = [];
pythonProcess.stdout.on('data', data => {
var myStr = data.toString();
var obj = JSON.parse(myStr);
lst.push(obj);
});
pythonProcess.on('close', (code) => cb([null, lst]));
pythonProcess.on('error', (err) => cb([err, lst]));
}
UPD на запрос про цикл и sleep:
(async () => {
let count = 100;
while (count--) {
console.log('async:', await drawAsync());
await delay(500);
}
})();
async function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
UPD2 на запрос про бесконечный вызов на callback-ах:
let f;
(f = () => {
drawCallback(([err, lst]) => {
if (err) {
console.error('cb error:', err);
}
console.log('cb:', lst);
setTimeout(f, 1000);
});
})();