jsrosetta

Bất đồng bộ

Message Passing

MessageChannel của Node.js so với channel (Go), mpsc (Rust), AsyncStream (Swift) và BlockingQueue (Java) để gửi dữ liệu giữa các tác vụ.

Phiên bản tối thiểu
Node.js ≥ 12.20Go ≥ 1.0Rust ≥ 1.58Swift ≥ 5.7Java ≥ 25
Đã chạy thử trên
Node.js 24.12.0Go 1.27.1Rust 1.98.1Swift 6.2.4Java 25.0.4.1

Code Node.js là ES module: lưu file .mjs hoặc đặt "type": "module" trong package.json.

Thay vì để hai tác vụ chạy song song cùng đọc/ghi một biến chung, cả năm ngôn ngữ đều cho phép gửi dữ liệu qua lại giữa chúng. Node.js làm việc này qua API MessageChannel/postMessage. Go có channel (chan) ở ngay cấp ngôn ngữ, với cú pháp riêng (<-, select) để gửi, nhận, đóng và chờ có timeout. Rust không có gì ở cấp ngôn ngữ cho việc này — std::sync::mpsc chỉ là một kiểu bình thường của thư viện chuẩn, gọi qua các phương thức thông thường (.send(), .recv(), .recv_timeout()) chứ không có cú pháp đặc biệt nào. Swift không có kiểu channel; AsyncStream là thứ gần nhất — một hàng đợi bất đồng bộ mà một phía yield() vào, phía kia đọc bằng for await, nhưng nó không có tính "block khi đầy" như channel thật. Java có BlockingQueue (SynchronousQueue, ArrayBlockingQueue…) — cách gần với channel của Go nhất trong ba ngôn ngữ còn lại.

Gửi dữ liệu giữa hai tác vụ (MessageChannel vs channel)

import { MessageChannel } from "node:worker_threads";
 
const { port1, port2 } = new MessageChannel();
 
port2.on("message", (msg) => {
  console.log("port2 received:", msg); // → port2 received: hello from port1
  port1.close();
  port2.close();
});
 
port1.postMessage("hello from port1");

Khác biệt chính

Node.js Go Rust Swift Java
Cơ chế MessageChannel/postMessage channel (chan) — cú pháp built-in của ngôn ngữ std::sync::mpsc — kiểu bình thường của thư viện chuẩn, không có cú pháp riêng AsyncStream — không block khi gửi BlockingQueue (SynchronousQueue…)
Giới hạn dung lượng không giới hạn, hàng đợi ẩn bên trong đặt buffer cố định lúc tạo (make(chan T, n)) sync_channel(n) cho buffer cố định không có backpressure thật ArrayBlockingQueue(n) cho buffer cố định
Chờ có timeout tự viết bằng Promise.race + setTimeout select + time.After trong cú pháp recv_timeout(Duration) đua bằng TaskGroup + Task.sleep poll(timeout, unit)

Tham khảo: github.com/miguelmota/golang-for-nodejs-developers#message-passing