2014-02-20 3 views
2

Node.js славится параллелизмом, однако я смущен тем, как заставить его работать одновременно. Я начал два запроса от Chrome один за другим очень быстро, и я ожидал, что выходы в консоли должны быть:Как сделать узел работает одновременно?

  1. «получить новый запрос»
  2. сразу после второго запроса «получить новый запрос "должны быть напечатаны
  3. через несколько секунд,„конец новый запрос“
  4. через несколько секунд,„конец новый запрос“

Однако то, что я увидел это:

  1. «получить новый запрос»
  2. через несколько секунд, «закончить новый запрос»
  3. «получить новый запрос»
  4. после нескольких секунд , закончить новый запрос

Это означает, что второй запрос не обрабатывается, пока первый не будет сделано. Ниже мой пример кода, что я пропустил?

var http = require("http"); 
    var url = require("url"); 

    function start(route) { 
    http.createServer(function(request, response) { 
     console.log('get a new request'); 

     // a time consuming loop   
     for (var i=0; i<10000000000; ++i) { 
     } 

     route(url.parse(request.url).pathname); 
     response.writeHead(200, {"Content-Type": "text/plain"}); 
     response.end(); 
     console.log('end the new request'); 
    }).listen(5858); 
    } 

    function saySomething(something) { 
    console.log(something); 
    } 

    exports.start = start; 
    exports.saySomething = saySomething; 
+1

Посмотрите на http://code.tutsplus.com/tutorials/node-js-for-beginners--net-26314 для учебника и на http://stackoverflow.com/questions/6898779/how -to-write-asynchronous-functions-for-node-js для возможного ответа – randunel

+0

node.js славится своей асинхронной моделью, я думаю, а не ее параллельной моделью. «Сервер» в этом случае должен обрабатывать обратные вызовы. –

ответ

3

Вам не нужно ничего делать.

Он основан на неблокирующих вводах-выводах. Проще говоря, есть цикл событий. Выполняется определенный набор синхронизирующих кодов, выполняется следующая итерация, которая запускает следующий набор кода синхронизации для запуска. В любое время запускается async op (db fetch, setTimeout, чтение файла и т. Д.) Запускается следующий тик цикла событий. Таким образом, никогда не будет ожиданий какого-либо кода.

Это не резьба. В вашем примере цикл for находится в одном непрерывном фрагменте кода, поэтому js будет запускать цикл for for, прежде чем он сможет обрабатывать другой HTTP-запрос.

Попробуйте положить setTimeout вокруг цикла for, чтобы узел мог перейти к следующему циклу событий и в вашем случае обработать веб-запрос.

+0

Зачем голосовать? – pbo

+0

Извините, это моя ошибка ... – buaaji

+0

Так, например, в цикле событий есть 10 запросов, первая из них отключена от цикла и обрабатывается сервером, и если есть время, требующее много времени, Вывода, первый запрос перейдет в спящий режим до тех пор, пока ввод-вывод не будет выполнен, и он будет поставлен в очередь до конца цикла событий. Поскольку первый запрос снова ставится в очередь, второй запрос затем получает возможность обрабатываться, это правильно? – buaaji

1
+0

Его код работает синхронно, я считаю, что автор хочет знать, как написать задержку асинхронизации :) Вы должны предложить 'setTimeout (callback, timeout)': P – randunel

+0

Erf. Правда. Возможно, я был ревностным. –

2

узел не может справиться с этим:

for (var i=0; i<10000000000; ++i) {} 

одновременно. Но он одновременно обрабатывает IO

+0

На самом деле это возможно, см. Мой обновленный ответ – GiveMeAllYourCats

-1

Это ожидаемое поведение, ̶ Мы называем это ̶ ̶b̶l̶o̶c̶k̶i̶n̶g̶. Раствор для погрузки-разгрузки Параллельное запрос будет сделать код ̶ ̶n̶o̶n̶-̶b̶l̶o̶c̶k̶i̶n̶g̶. Как только вы называли ̶ ̶ ̶r̶e̶s̶p̶o̶n̶s̶e̶.̶w̶r̶i̶t̶e̶H̶e̶a̶d̶ Код, начало блокировать Ожидают ̶ ̶r̶e̶s̶p̶o̶n̶s̶e̶.̶e̶n̶d̶ ̶.

EDIT 7/8/14: бы справиться с этой проблемой в последнее время и выяснил, вы можете использовать темы для этого: https://www.npmjs.org/package/webworker-threads

WebWorker-резьба обеспечивает асинхронный API для CPU переплете задача что не хватает в Node.js:

var Worker = require('webworker-threads').Worker; 
require('http').createServer(function (req,res) { 
    var fibo = new Worker(function() { 
    function fibo (n) { 
     return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; 
    } 
    this.onmessage = function (event) { 
     postMessage(fibo(event.data)); 
    } 
    }); 
    fibo.onmessage = function (event) { 
    res.end('fib(40) = ' + event.data); 
    }; 
    fibo.postMessage(40); 
}).listen(port); 

И это не будет блокировать цикл обработки событий, потому что для каждого запроса фибо работник будет работать параллельно в сен arate background thread.

+0

Благодарим вас за объяснение, однако ваше решение не может решить мою проблему, последовательность вывода не изменяется. Точно так же, как [pbo] (http://stackoverflow.com/users/688940/pbo) сказал, что setTimeout может сделать трюк. – buaaji

+0

setTimeout или функция может работать в этих случаях, вопрос в том, хотите ли вы, чтобы код выполнялся напрямую с помощью функции или выполнял ее с задержкой с помощью setTimeout. Дело в том, что код блокировки должен находиться в разных циклах событий, будь то через setTimeout или функцию. – GiveMeAllYourCats

+0

Я не понимаю ... почему функция timeConsumingLoop может отложить выполнение цикла занятости? Я пробовал ваш код, а выходы: get/end, get/end, get/end ... – buaaji

Смежные вопросы