2011-08-28 23 views
34

Trong trình duyệt, nếu bạn sử dụng setTimeout từ bên trong một hàm được gọi là setTimeout thì thời gian trễ tối thiểu là 4ms sẽ được thực thi. Wiki nhà phát triển của Mozilla describes this behaviour và đề cập rằng nó có become standardized in HTML5.Node.js có thực thi độ trễ tối thiểu cho setTimeout không?

Số documentation for setTimeout của Node.js không đề cập đến độ trễ tối thiểu. Tuy nhiên, tài liệu cho the process.nextTick function mô tả nó như là một giải pháp thay thế hiệu quả hơn cho setTimeout(fn, 0). Điều này cho thấy khả năng nó hiệu quả hơn vì nó tránh được sự chậm trễ này. Nếu không, setTimeout(fn, 0) có thể được tối ưu hóa để hoạt động giống nhau.

Node.js có thực thi một độ trễ tối thiểu cho setTimeout, khi trình duyệt web hoạt động không?

Trả lời

17

Nó không có độ trễ tối thiểu và đây thực sự là vấn đề tương thích giữa trình duyệt và nút. Bộ hẹn giờ hoàn toàn không được chỉ định trong JavaScript (đó là đặc tả DOM không sử dụng trong Node và thậm chí không được theo dõi bởi trình duyệt) và nút triển khai chúng đơn giản chỉ vì chúng cơ bản trong lịch sử JavaScript và cách chúng không thể thay thế được.

Nút sử dụng libuv là lớp trừu tượng đa nền tảng cho các hệ thống cấp thấp hơn như hệ thống tệp, công cụ mạng, v.v. Một trong số đó là bộ hẹn giờ, Node cung cấp trình bao bọc tối thiểu. Ở cấp độ libuv, bộ định thời được sử dụng là các bộ định thời độ chính xác cao cho hệ thống. Trong Windows, ví dụ, điều này được thực hiện bằng cách sử dụng QueryPerformanceFrequencyFileTimeToSystemTime cung cấp độ phân giải được đo bằng nano giây.

Trong nút, nếu bạn chỉ định setTimeout(callback, 1) thì nó sẽ được thực hiện sau một phần nghìn giây (giả sử hệ thống không trì hoãn do bị choáng ngợp). Trong trình duyệt, thời gian tối thiểu sẽ là 4 mili giây như được chỉ định bởi thông số HTML5: https://developer.mozilla.org/en/DOM/window.setTimeout. Đây không phải là thời gian được đảm bảo, chỉ là tối thiểu.Hầu hết các trình duyệt có thể được mong đợi có độ phân giải ~ 15ms ảnh hưởng đến hoạt ảnh DOM.

Một phần thông tin hợp lệ là thời gian chờ được đặt thành cùng một mili giây, trong cùng một khung, sẽ được thực thi theo thứ tự chúng được xếp hàng đợi. Nếu bạn phải làm:

setTimeout(callback1, 1); 
    setTimeout(callback2, 1); 
    setTimeout(callback3, 1); 
    setTimeout(callback4, 1); 

Tất cả trong một khối, Nút phải gọi chúng theo thứ tự đó. Điều này chỉ áp dụng nếu chúng có cùng thời gian phân giải chính xác.

http://msdn.microsoft.com/en-us/library/windows/desktop/ms644905(v=vs.85).aspx

http://msdn.microsoft.com/en-us/library/windows/desktop/ms724280(v=vs.85).aspx

15

Từ thử nghiệm này, có vẻ như nó không có độ trễ tối thiểu.

Nếu bạn làm một setTimeout() mà có một thời gian 10ms, và dài giá trị trở lại giao diện điều khiển, đây là những gì bạn nhận được:

var timer = setTimeout(function(){ console.log(timer);}, 10); 

{ _idleTimeout: 10, 
    _onTimeout: [Function], 
    _idlePrev: null, 
    _idleNext: null, 
    _idleStart: Sun, 28 Aug 2011 14:34:41 GMT } 

Tương tự như vậy, với một thời gian 1ms, bạn nhận được:

var timer = setTimeout(function(){ console.log(timer);}, 1); 

{ _idleTimeout: 1, 
    _onTimeout: [Function], 
    _idlePrev: null, 
    _idleNext: null, 
    _idleStart: Sun, 28 Aug 2011 14:34:59 GMT } 

Nhưng nếu bạn thực hiện thời lượng 0, bạn hoàn toàn không nhận được thuộc tính _idleTimeout:, có vẻ như gợi ý rằng cuộc gọi lại được gọi ngay lập tức, mặc dù không đồng bộ.

var timer = setTimeout(function(){ console.log(timer);}, 0); 

{ repeat: 0, callback: [Function] } 

Hơn nữa, nếu tôi làm đơn giản so sánh ngày bắt đầu/kết thúc, tôi thường được 0 là kết quả của trừ khi bắt đầu từ kết thúc.

var start = Date.now(); 
var timer = setTimeout(function(){ console.log(timer, Date.now() - start);}, 0); 

{ repeat: 0, callback: [Function] } 0 

Các thử nghiệm này được thực hiện bằng cách sử dụng Node.js 0.5.2.

1

Cần lưu ý rằng việc thực hiện hẹn giờ sẽ khác nhau tùy theo hệ điều hành. Ví dụ, tôi nhớ một vấn đề JTimer "tốt" cũ, nơi độ phân giải của bộ đếm thời gian là 16ms trên Windows và ~ 1ms trên các nền tảng khác. Nó gần như chắc chắn là giá trị thử nghiệm trên máy chủ cụ thể của bạn.

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