jsrosetta

Bất đồng bộ

Timer: setTimeout và setInterval

setTimeout và setInterval của Node.js so với time.AfterFunc/Ticker (Go), std::thread (Rust), Task.sleep (Swift) và ScheduledExecutorService (Java).

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.

Node.js chạy callback của setTimeout/setInterval trên event loop, nên chương trình vẫn sống cho tới khi hàng đợi callback trống. Ở phần chạy một lần, Go, Rust và Java đều chạy callback trên một thread/goroutine riêng — nếu không có gì giữ luồng chính lại (sync.WaitGroup, JoinHandle::join, CountDownLatch), chương trình có thể thoát trước khi callback kịp chạy — còn Swift là ngoại lệ: Task.sleep chạy ngay trong task hiện tại nên không cần cơ chế chờ riêng. Ở phần lặp lại thì khác: time.Ticker của Go và channel của Rust không "chạy callback" — chúng gửi tick qua một channel/hàng đợi mà code gọi phải tự đọc, AsyncStream của Swift cũng vậy (yield tick cho vòng for await đọc); riêng Java vẫn dùng callback thật qua scheduleAtFixedRate, giống hệt setInterval.

Chạy một lần sau một khoảng thời gian (setTimeout / time.AfterFunc)

setTimeout(callback, 1000);
 
function callback() {
  console.log("called"); // → called (sau ~1s)
}

Chạy lặp lại theo chu kỳ (setInterval / time.Ticker)

let i = 0;
 
const id = setInterval(callback, 1000);
 
function callback() {
  console.log("called", i);
 
  if (i === 3) {
    clearInterval(id);
  }
 
  i++;
}
// → called 0
// → called 1
// → called 2
// → called 3

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