Node.js và Python là hai ngôn ngữ ưa chuộng nhất của các nhà phát triển và thiết kế web. Tuy nhiên, có những lĩnh vực Node.js kém hơn Python là tính toán số học và khoa học (AI, Machine learning, deep learning...). Trong khi Python cung cấp nhiều thư viện làm việc với tính toán khoa học dễ dàng hơn.
May mắn thay, chúng ta có thể tận dụng các thư viện Python trong ứng dụng Node.js bằng cách chạy Python ở nền và trả kết quả về.
Để làm điều này, chúng ta sẽ sử dụng thư viện chuẩn child_process của Node.js để tạo một tiến trình Python ở nền, thực hiện tính toán và trả kết quả về chương trình Node.
Script Python
Chúng ta sẽ viết một script Python đơn giản xuất ra thông điệp đến đầu ra tiêu chuẩn trong quá trình chạy.
# Nhập thư viện
import sys, getopt, time
def main(argv):
argument = ''
usage = 'usage: myscript.py -f '
# Phân tích đối số đầu vào
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
# In đầu ra
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:])
Kết quả
>python myscript.py -f "Hello, Python" Start : Wed Feb 20 07:52:45 2019 Foo is Hello, Python End : Wed Feb 20 07:52:49 2019
Sẽ tạo ra cùng đầu ra như trên nếu chạy với đối số:
>python myscript.py --foo "Hello, Python" >python myscript.py –h
Kết quả
usage: myscript.py -f
Tương tác Node.js
Script Node.js sẽ tương tác với script Python bằng cách gọi script Python trước, sau đó chuyển đầu ra của script tới client và hiển thị đầu ra ở client.
Hãy tạo script Node.js, nơi chúng ta sẽ tạo tiến trình con bằng phương thức spawn().
server.js
const path = require('path')
const {spawn} = require('child_process')
/**
* Chạy python myscript, truyền `-u` để không đệm đầu ra console
* @return {ChildProcess}
*/
function runScript(){
return spawn('python', [
"-u",
path.join(__dirname, 'myscript.py'),
"--foo", "some value for foo",
]);
}
const subprocess = runScript()
// In đầu ra của script
subprocess.stdout.on('data', (data) => {
console.log(`data:${data}`);
});
subprocess.stderr.on('data', (data) => {
console.log(`error:${data}`);
});
subprocess.stderr.on('close', () => {
console.log("Closed");
});
Script trên sẽ cho đầu ra thông qua .on('data', callback). Để ngăn Python đệm đầu ra, hãy sử dụng cờ –u (không phải –f như văn bản gốc), nếu không sự kiện data sẽ không nhận được câu lệnh print() từ chương trình cho đến khi kết thúc thực thi.
>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