2012-11-19 8 views
50

Zgodnie z Understanding the node.js event loop, node.js obsługuje model pojedynczego wątku. Oznacza to, że jeśli wykonam wiele żądań do serwera node.js, nie będzie on odradzał nowego wątku dla każdego żądania, ale wykona każde żądanie pojedynczo. Oznacza to, że jeśli wykonam następujące polecenie dla pierwszego żądania w moim kodzie node.js, a w międzyczasie nowe żądanie przychodzi do węzła, drugie żądanie musi poczekać do zakończenia pierwszego żądania, w tym 5 sekund czasu uśpienia. Dobrze?Jak zasnąć wątek w pliku node.js bez wpływu na inne wątki?

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

Czy istnieje sposób, że node.js może tarła nowego wątku dla każdego żądania tak, że drugi wniosek nie trzeba czekać na pierwsze żądanie uzupełnienia, czy mogę zadzwonić spać tylko na konkretnym wątku?

+3

nie musisz tak spać. Zamiast tego powinieneś rzucić okiem na setTimeout -> http://nodejs.org/api/globals.html#globals_settimeout_cb_ms – Alfred

Odpowiedz

92

Jeśli odwołujesz się do modułu npm sleep, w pliku readme zapisano, że sleep zablokuje wykonanie. Masz rację - nie jest to, czego chcesz. Zamiast tego chcesz użyć setTimeout, który nie jest blokowany. Oto przykład:

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

Dla każdego, kto chce to zrobić przy użyciu ES7 asynchroniczny/Oczekujcie Ten przykład powinien pomóc:

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

, więc node.js wykona jedno żądanie naraz, co oznacza, że ​​następuje po modelu z pojedynczym wątkiem. Dobrze? – emilly

+6

Tak, używa pojedynczego wątku wykonania, więc może obliczać tylko jedno żądanie naraz, ale może mieć zdarzenia oczekujące na wiele żądań. Kiedy wywołujesz 'setTimeout', przechowuje ono zdarzenie w kolejce i może rozpocząć wykonywanie następnego żądania. Po pięciu sekundach zdarzenie zostanie usunięte z kolejki i nastąpi wywołanie zwrotne (w tym przypadku funkcja zawierająca "console.log"). –

+0

Spójrz na [ten screencast] (http://nodecasts.net/episodes/1-introduction-to-nodejs), aby dowiedzieć się więcej o tym, jak Node.js uruchamia wiele żądań bez konieczności "czekania" na siebie nawzajem . –

0

W przypadku gdy masz pętlę z żądania asynchronicznego w każdy z nich ma pewien czas między każdym żądaniem, możesz użyć tego kodu:

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++; 
     } 
    } 

Ten przykład czeka 1 sekundę po każdym ponownym zadanie przed wysłaniem następnego.

+0

-1. To ** NIE ** będzie robić to, czego się spodziewasz. Pętla NIE działa asynchronicznie. Natychmiast wyśle ​​wszystkie żądania. Bądź ostrożny, gdy myślisz o pętli z asynchronią - ta kombinacja jest trudna. – treecoder

+0

Oczywiście pętla zostanie wywołana wszystkie naraz. Ale timon zwiększa każdą pętlę. Tak więc 1 sekunda ... 2 sekundy ... 3 sekundy. Dlatego "myAsyncFunc" będzie wywoływany co sekundę zamiast wszystkich naraz. Działa zgodnie z oczekiwaniami, kiedy go testuję.Czy możesz mi powiedzieć, co myślisz, że jest z nim nie tak? – Jodo

+0

Kod działa, przy okazji, w nieco trudny sposób. Funkcja _startTimeout_ jest wywoływana 10 razy od razu, ale każde wywołanie ma timeout o jedną sekundę większą, więc każde wywołanie _myAsyncFunc_ jest wywoływane sekundę później. – greuze

Powiązane problemy