2012-01-21 31 views
5

Nếu tôi có một hàm setTimeout() đơn giản và đặt trong 10 giây ...Trong Node.js, setTimeout() có chặn vòng lặp sự kiện không?

Toàn bộ máy chủ đã chết trong 10 giây đó ??? Điều này có đúng không? Đó là những gì tôi đã nghe.

+1

Câu trả lời ngắn gọn: không. – voithos

+0

@voithos thì đây là gì? http://stackoverflow.com/questions/8949465/node-js-how-would-you-recreate-the-settimeout-function-without-it-blocking-th – TIMEX

+1

Bạn đã đọc câu trả lời trong liên kết đó chưa? Không phải 'setTimeout' đã chặn vòng lặp sự kiện, đó là hàm' wait() 'mà chúng đã thực hiện. Nó, theo nghĩa đen, chỉ cần chờ đợi số tiền nhất định của thời gian (với một vòng lặp trong khi, không ít)! Tất nhiên nó sẽ chặn. 'setTimeout' không hoạt động theo cách đó. – voithos

Trả lời

19

Câu trả lời là không. Những gì liên kết của bạn Node.js: How would you recreate the 'setTimeout' function without it blocking the event loop? đã cho thấy không phải là setTimeout chặn vòng lặp sự kiện đó là một vòng lặp whilecố tình chặn vòng lặp sự kiện. Nếu bạn muốn máy chủ của bạn được nhanh chóng, bạn không muốn chặn vòng lặp sự kiện. Một cuộc gọi lại không đồng bộ như setTimeout sẽ hoạt động tốt.

bạn đang cố gắng để ngăn chặn đối với một số lý do (như thử nghiệm hoặc một cái gì đó?)

+0

Ngoài ra, mọi thứ ở trên cũng áp dụng cho setInterval. – alessioalex

2

Điều đó không đúng. Khi bạn gọi setTimeout và trả lại mã, máy chủ không bị chặn. Hoàn toàn miễn phí để xử lý các sự kiện khác (có thể là các cuộc gọi lại setTimeout khác) trong khi chờ bộ hẹn giờ cụ thể của bạn kích hoạt

2

Các liên kết mà bạn dường như bị lẫn lộn về làm không trạng thái đó setTimeout sẽ chặn. Thay vào đó, OP trong câu hỏi đó đang cố gắng thực hiện một hàm tùy chỉnh có tên là wait sẽ hoạt động như setTimeout. Chức năng wait là chức năng chặn - setTimeout sẽ không chặn.

4

Một phát hiện khác có thể giúp những người khác đang học Node.js và tò mò về câu hỏi này, nhưng bị lừa bởi hành vi ẩn của các trình duyệt hiện đại.

Mã thực sự đơn giản, tôi chỉ muốn kiểm tra sự hiểu biết của mình về "bản chất không đồng bộ" của Node.js.

var express = require('express'); 
var router = express.Router(); 

router.get('/', function(req, res, next) { 
    console.log("route begin"); 
    var start = new Date(); 


    setTimeout(function() { 
     res.render('index', { title: start + ' - ' + new Date()}); 
    }, 20000);//force delay of 20 seconds. 

    console.log("route end"); 
}); 

module.exports = router; 

Nếu tôi bắt đầu ba cửa sổ trình duyệt (Firefox, chính xác hơn), mở URL xác định bởi tuyến đường này cùng một lúc, và kiểm tra log giao diện điều khiển từ Node.js, rõ ràng yêu cầu không phải là được xử lý đồng thời!

Tôi đã thử nghiệm nhiều lần, kết quả giống nhau.

Sản lượng nhật ký điển hình là như thế này:

route begin at: Fri Aug 28 2015 18:35:57 GMT+0800 (CST) 
route end at: Fri Aug 28 2015 18:35:57 GMT+0800 (CST) 
route begin at: Fri Aug 28 2015 18:36:18 GMT+0800 (CST) 
route end at: Fri Aug 28 2015 18:36:18 GMT+0800 (CST) 
route begin at: Fri Aug 28 2015 18:36:20 GMT+0800 (CST) 
route end at: Fri Aug 28 2015 18:36:20 GMT+0800 (CST) 

Và cũng có thể, kỳ lạ, nó không được chạy trong chế độ nối tiếp hoặc (nếu Node.js bị chặn bởi setTimeout, nó nên). Khoảng thời gian giữa yêu cầu đầu tiên và thứ hai là 20 giây, nhưng giây thứ hai và thứ ba chỉ là 2 giây.

Sau khi gãi đầu trong một thời gian, tôi đột nhiên nhớ rằng trình duyệt có giới hạn kết nối trên cùng một máy chủ!

Vì vậy, tôi nhanh chóng thiết lập một thử nghiệm khác, nhưng lần này bằng cách phát hành nhiều lệnh curl thay thế.

Hallelujah!

route begin at: Fri Aug 28 2015 18:42:51 GMT+0800 (CST) 
route end at: Fri Aug 28 2015 18:42:51 GMT+0800 (CST) 
route begin at: Fri Aug 28 2015 18:42:53 GMT+0800 (CST) 
route end at: Fri Aug 28 2015 18:42:53 GMT+0800 (CST) 
route begin at: Fri Aug 28 2015 18:42:55 GMT+0800 (CST) 
route end at: Fri Aug 28 2015 18:42:55 GMT+0800 (CST) 
0

Quá trình chính dường như được monothreaded bởi máy chủ và bị chặn bởi một setTimeout hoặc một while.

Tuy nhiên, có một sự thay thế với mã này mà làm việc như mong đợi và không chặn quá trình chính hoặc vòng lặp sự kiện:

var express = require('express') 
var app = express() 

function setTimeoutAsync (callback, time) { 
    setTimeout(function() { 
    callback() 
    }, time) 
    return 0 
} 

app.get('/', function (req, res, next) { 
    console.log("route begin") 
    var start = +new Date() 
    setTimeoutAsync(function() { 
     console.log("route done") 
     res.json({ delay: ((+new Date()) - start) + 'ms' }) 
    }, 5000) 
    console.log("route end") 
}); 

app.listen(8000) 

Trong terminal:

route begin // first page 
route end 
route begin // second page 
route end 
route begin // third page 
route end 
route done // first render 
route done // second render 
route done // third render 

Tốt nguồn:

https://www.journaldev.com/7462/node-js-architecture-single-threaded-event-loop

https://nodejs.org/en/docs/guides/blocking-vs-non-blocking/

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