2012-11-19 27 views
50

Theo Understanding the node.js event loop, node.js hỗ trợ một mô hình chuỗi đơn. Điều đó có nghĩa là nếu tôi thực hiện nhiều yêu cầu đến một máy chủ node.js, nó sẽ không sinh ra một luồng mới cho mỗi yêu cầu nhưng sẽ thực hiện từng yêu cầu một. Nó có nghĩa là nếu tôi làm như sau cho yêu cầu đầu tiên trong mã node.js của tôi, và trong khi đó một yêu cầu mới xuất hiện trên nút, yêu cầu thứ hai phải chờ cho đến khi yêu cầu đầu tiên hoàn thành, bao gồm 5 giây thời gian ngủ. Đúng?Làm thế nào để ngủ thread trong node.js mà không ảnh hưởng đến các chủ đề khác?

var sleep = require('sleep'); 
    sleep.sleep(5)//sleep for 5 seconds 

Có cách nào mà Node.js có thể đẻ trứng một chủ đề mới cho mỗi yêu cầu để yêu cầu thứ hai không phải chờ đợi cho yêu cầu đầu tiên để hoàn thành, hoặc tôi có thể gọi giấc ngủ trên chỉ đề cụ thể?

+3

bạn không cần phải ngủ như thế. Thay vào đó, bạn nên xem setTimeout -> http://nodejs.org/api/globals.html#globals_settimeout_cb_ms – Alfred

Trả lời

92

Nếu bạn đang tham chiếu đến mô-đun npm sleep, ghi chú trong readme rằng sleep sẽ chặn thực thi. Vì vậy, bạn là đúng - nó không phải là những gì bạn muốn. Thay vào đó bạn muốn sử dụng setTimeout không bị chặn. Dưới đây là một ví dụ:

setTimeout(function() { 
    console.log('hello world!'); 
}, 5000); 

Đối với bất cứ ai tìm cách để làm điều này bằng ES7 async/chờ đợi, ví dụ này sẽ giúp:

const snooze = ms => new Promise(resolve => setTimeout(resolve, ms)); 

const example = async() => { 
    console.log('About to snooze without halting the event loop...'); 
    await snooze(1000); 
    console.log('done!'); 
}; 

example(); 
+0

để node.js sẽ thực thi một yêu cầu tại một thời điểm có nghĩa là nó tuân theo mô hình luồng đơn. Đúng? – emilly

+6

Có, nó sử dụng một luồng đơn lẻ để thực thi nó chỉ có thể tính toán một yêu cầu một lần, nhưng có thể có các sự kiện đang chờ xử lý trên nhiều yêu cầu. Khi bạn gọi 'setTimeout', nó lưu trữ sự kiện trong hàng đợi và sau đó có thể bắt đầu thực hiện yêu cầu tiếp theo. Sau năm giây, sự kiện sẽ bị xóa khỏi hàng đợi và lệnh gọi lại sẽ được thực thi (hàm chứa 'console.log' trong trường hợp này). –

+0

Hãy xem [this screencast] (http://nodecasts.net/episodes/1-introduction-to-nodejs) để biết thêm chi tiết về cách Node.js chạy nhiều yêu cầu mà không làm cho chúng "chờ" trên nhau . –

0

Trong trường hợp bạn có một vòng lặp với một yêu cầu async trong mỗi một và bạn muốn có một thời gian nhất định giữa mỗi yêu cầu bạn có thể sử dụng mã này:

var startTimeout = function(timeout, i){ 
     setTimeout(function() { 
      myAsyncFunc(i).then(function(data){ 
       console.log(data); 
      }) 
     }, timeout); 
    } 

    var myFunc = function(){ 
     timeout = 0; 
     i = 0; 
     while(i < 10){ 
      // By calling a function, the i-value is going to be 1.. 10 and not always 10 
      startTimeout(timeout, i); 
      // Increase timeout by 1 sec after each call 
      timeout += 1000; 
      i++; 
     } 
    } 

Ví dụ này chờ 1 giây sau mỗi lần nhiệm vụ trước khi gửi tiếp.

+0

-1. Đây là ** KHÔNG ** sẽ làm những gì bạn mong đợi. Vòng lặp KHÔNG chạy không đồng bộ. Nó sẽ kích hoạt tất cả các yêu cầu ngay lập tức. Hãy rất cẩn thận khi suy nghĩ vòng lặp với async - sự kết hợp này là khó khăn. – treecoder

+0

Tất nhiên vòng lặp được gọi là tất cả cùng một lúc. Nhưng thời gian chờ tăng mỗi vòng lặp. 1 giây ... 2 giây ... 3 giây Đó là lý do tại sao "myAsyncFunc" sẽ được gọi mỗi giây thay vì tất cả cùng một lúc. Nó hoạt động như mong đợi khi tôi thử nghiệm nó.Bạn có thể cho tôi biết bạn nghĩ gì không? – Jodo

+0

Mã DOES hoạt động, bằng cách này, theo một cách ít phức tạp. Hàm _startTimeout_ được gọi 10 lần ngay lập tức, nhưng mỗi cuộc gọi có thời gian chờ lớn hơn một giây, vì vậy mọi lời gọi đến _myAsyncFunc_ được gọi một giây sau đó. – greuze

Các vấn đề liên quan