Node.js และ Python เป็นภาษายอดนิยม แต่ Node.js อ่อนในการคำนวณเชิงตัวเลขและวิทยาศาสตร์ (AI, ML, Deep Learning) ในขณะที่ Python มีไลบรารีครบครัน สามารถรวมทั้งสองได้โดยรัน Python ในพื้นหลังและส่งผลกลับมายัง Node.js
วิธีการ
ใช้ child_process ของ Node.js สร้าง child process ด้วย spawn() รัน Python script คำนวณ และส่งผลลัพธ์กลับมา
Python Script (myscript.py)
import sys, getopt, time
def main(argv):
argument = ''
usage = 'usage: myscript.py -f '
try:
opts, args = getopt.getopt(argv, "hf:", ["foo="])
except getopt.GetoptError:
print(usage)
sys.exit(2)
for opt, arg in opts:
if opt == '-h':
print(usage)
sys.exit()
elif opt in ("-f", "--foo"):
argument = arg
# พิมพ์ผลลัพธ์พร้อมหน่วงเวลา
print("Start : %s" % time.ctime())
time.sleep(2)
print('Foo is')
time.sleep(2)
print(argument)
print("End : %s" % time.ctime())
if __name__ == "__main__":
main(sys.argv[1:])
Node.js Script (server.js)
const path = require('path')
const {spawn} = require('child_process')
function runScript() {
return spawn('python', [
"-u", // unbuffered output
path.join(__dirname, 'myscript.py'),
"--foo", "some value for foo",
])
}
const subprocess = runScript()
// รับข้อมูลจาก stdout
subprocess.stdout.on('data', (data) => {
console.log(`data:${data}`);
});
// รับข้อผิดพลาดจาก stderr
subprocess.stderr.on('data', (data) => {
console.log(`error:${data}`);
});
// เมื่อ process จบ
subprocess.on('close', () => {
console.log("Closed");
});
ผลลัพธ์
> node server.js
data:Start : Wed Feb 20 10:56:11 2019
data:Foo is
data:some value for foo
data:End : Wed Feb 20 10:56:15 2019
Closed
จุดสำคัญ
- ใช้ flag
-uเพื่อปิด buffering ของ Python output ไม่งั้นข้อมูลจะไม่ส่งมา real-time - ส่งอาร์กิวเมนต์ไปยัง Python script ได้ผ่าน array ตัวที่ 2 ของ spawn()
- เหมาะสำหรับการรัน ML models, คำนวณซับซ้อน หรืองานที่ Python เก่งกว่า