2011-11-13 45 views
54

Tôi đã thấy process.nextTick được sử dụng ở một vài địa điểm và không thể nói rõ những gì nó đang được sử dụng.Trường hợp sử dụng thích hợp cho process.nextTick trong Node.js là gì?

các trường hợp sử dụng chính/đúng process.nextTick trong Node.js là gì? Các tài liệu về cơ bản nói rằng đó là một cách tối ưu hơn để làm setTimeout, nhưng điều đó không giúp ích gì nhiều.

Tôi đã từng làm rất nhiều ActionScript, vì vậy ý ​​tưởng "đợi cho đến khi khung tiếp theo" thực thi mã có ý nghĩa ở một mức nào đó - nếu bạn đang chạy một hoạt ảnh, bạn có thể cập nhật mọi khung hình thay vì mili giây chẳng hạn. Nó cũng có ý nghĩa khi bạn muốn phối hợp thiết lập một loạt các biến - bạn thay đổi các biến trong khung 1, và áp dụng các thay đổi trong khung 2. Flex thực hiện một cái gì đó như thế này trong vòng đời thành phần của họ.

Câu hỏi của tôi là, tôi nên sử dụng điều này trong JavaScript phía máy chủ? Tôi không thấy bất cứ nơi nào ngay lập tức, nơi bạn cần loại điều khiển luồng/hiệu suất tinh chỉnh này. Chỉ cần tìm một điểm đúng hướng.

+2

Howtonode có một [bài viết tuyệt vời về sự hiểu biết 'process.nextTick()'] (http://howtonode.org/understanding-process-next-tick) –

Trả lời

67

process.nextTick đặt gọi lại vào hàng đợi. Mỗi cuộc gọi lại trong hàng đợi này sẽ được thực thi ngay từ đầu của dấu tick tiếp theo của vòng lặp sự kiện. Nó cơ bản được sử dụng như một cách để xóa ngăn xếp cuộc gọi của bạn. Khi tài liệu nói nó giống như setTimeout, điều đó có nghĩa là nó giống như sử dụng setTimeout(function() { ... }, 1) trong trình duyệt. Nó có cùng các trường hợp sử dụng.

Một trường hợp sử dụng mẫu sẽ là, bạn tạo một hàm tạo cho một số đối tượng cần sự kiện được liên kết với nó. Tuy nhiên, bạn không thể bắt đầu phát ra sự kiện ngay lập tức, bởi vì mã khởi tạo nó chưa có thời gian để liên kết với các sự kiện. Gọi hàm tạo của bạn nằm phía trên chúng trong ngăn xếp cuộc gọi và nếu bạn tiếp tục làm những thứ đồng bộ, nó sẽ vẫn như vậy. Trong trường hợp này, bạn có thể sử dụng process.nextTick trước khi tiếp tục với bất kỳ điều gì bạn sắp thực hiện. Nó đảm bảo rằng người sử dụng hàm tạo của bạn sẽ có đủ thời gian để ràng buộc các sự kiện.

Ví dụ:

var MyConstructor = function() { 
    ... 
    process.nextTick(function() { 
    self._continue(); 
    }); 
}; 

MyConstructor.prototype.__proto__ = EventEmitter.prototype; 

MyConstructor.prototype._continue = function() { 
    // without the process.nextTick 
    // these events would be emitted immediately 
    // with no listeners. they would be lost. 
    this.emit('data', 'hello'); 
    this.emit('data', 'world'); 
    this.emit('end'); 
}; 

Ví dụ Middleware sử dụng constructor này

function(req, res, next) { 
    var c = new MyConstructor(...); 
    c.on('data', function(data) { 
    console.log(data); 
    }); 
    c.on('end', next); 
} 
+0

Cảm ơn người đàn ông, điều này đã làm cho nó rõ ràng. –

+1

Ngoài ra, setTimeout quá chậm. – Parris

+3

"Mọi cuộc gọi lại trong hàng đợi này sẽ được thực thi ngay từ đầu của dấu tick tiếp theo của vòng lặp sự kiện." Tôi nghĩ rằng điều này không hoàn toàn chính xác nữa. Như tôi đã hiểu, hàng đợi được xử lý ở cuối dấu tick hiện tại. "Trong v0.10, các trình xử lý nextTick chạy ngay sau mỗi cuộc gọi từ C++ sang JavaScript. Điều đó có nghĩa là, nếu mã JavaScript của bạn gọi process.nextTick, thì cuộc gọi lại sẽ kích hoạt ngay khi mã chạy xong, nhưng trước khi quay lại vào vòng lặp sự kiện. " - từ [thông báo của nút 0.10.0] (http://blog.nodejs.org/2013/03/11/node-v0-10-0-stable/) –

15

Nó chỉ đơn giản đặt chức năng của bạn ở phần cuối của vòng lặp sự kiện. Thông thường khi bạn đang thực hiện một số xử lý đồng bộ nặng, tốt hơn là sử dụng process.nextTick cho mọi đoạn mã, để đảm bảo rằng quá trình sẽ không chặn các sự kiện khác. Khi bạn làm điều đó, sau khi nó đạt đến proess.nextTick và hàm kết thúc, nó xử lý các sự kiện khác như các yêu cầu http, sau đó nó đạt đến process.nextTick gọi lại và thực hiện nó.

Khác với điều đó nếu bạn có thể sử dụng nó để chạy một hàm đệ quy, mà không nhận được cuộc gọi ngăn xếp tràn!

Chỉnh sửa: Hiện tại có node's setImmediate function chức năng của lịch biểu đó sẽ được chạy sau các sự kiện I/O đang chờ xử lý (như xử lý yêu cầu web mới): Tôi đã giải thích một số use case in the answer of this question.

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