Как разработать стратегию выполнения node.js?

Подход Node.js основан на событиях, и мне было интересно, как бы вы решили проблему запуска события?

Допустим, у нас есть какие-то действия в веб-приложении: создание данных, обслуживание страниц, получение данных и т. д.

Как бы вы изложили эти события? В резьбовой системе конструкция довольно «простая». Вы выделяете потоки для определенного набора задач и идете по пути синхронизации потоков. Пока эти задачи находятся на низком уровне по запросу, потоки простаивают и ничего не делают. Когда они нужны, они запускают свой код. Хотя у этой дороги есть проблемы, они хорошо задокументированы и вроде как решены.

Мне трудно понять, как работает событие node.js. У меня есть 10 запросов, но я не создал никаких данных, поэтому я не могу их обслужить, создание данных - это долгое действие, и еще 5 клиентов хотят отправить данные. Что теперь?

Я создал следующий непроверенный код, который в основном представляет собой кучу обратных вызовов, которые регистрируются и должны выполняться. Будет какой-то менеджер свай, который запустится и решит, какой код он хочет выполнить сейчас. Весь обратный вызов, созданный этим обратным вызовом, может быть добавлен «естественным образом» в четный цикл. Он также должен зарегистрировать себя, чтобы цикл событий мог вернуть ему управление. Другие вещи, такие как статический контент и все, что когда-либо может быть связано по-разному.

  1. Как я могу зарегистрировать обратный вызов, чтобы он был последним вызовом в текущем состоянии цикла событий?
  2. Это хороший способ решить эту проблему?

person qballer    schedule 09.08.2012    source источник
comment
Вы можете проверить этот другой ответ, который, кажется, о том же, но под другим углом.   -  person Edwin Dalorzo    schedule 07.04.2019
comment
Но подведем итог: сравните это с тем, как работает ваша аппаратная архитектура. Ваш процессор намного быстрее вашего жесткого диска, когда вы хотите прочитать файл, ОС регистрирует прерывание, чтобы получить уведомление, когда данные доступны в дисковом буфере, а тем временем она уходит и делает что-то еще. ЦП всегда занят. Когда в дисковом буфере есть доступные данные, генерируется прерывание, и ОС может выделить для него некоторый ЦП. Таким образом, никогда не было потока, ожидающего. Тот же принцип в NIO. Код никогда не блокирует поток. Когда есть работа, которую нужно сделать, поток будет назначен для ее выполнения.   -  person Edwin Dalorzo    schedule 07.04.2019


Ответы (2)


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

Например:

 app.get('/details/:id?', function (req, res) {
    var id = req.params.ucid,
        publish = function (data) {
            res.send(data);
        };
    service.getDetails(id, publish);
});

Затем вы можете вызвать метод публикации из вашего метода получения сведений после того, как вы создали необходимые данные.

getDetail : function (id, callback) {
    var data = makeMyData(id);
    callback(data)
}

Который затем опубликует ваши данные обратно в объект ответа. Из-за цикла событий узел будет продолжать обслуживать запросы к этому URL-адресу, не прерывая генерацию данных с первого запроса.

person Mark Taylor    schedule 09.08.2012
comment
Итак, поскольку вы регистрируете обратный вызов и не возвращаете значение из функции, вы фактически позволяете циклу обработки событий обрабатывать его? не вычисляет ли обратный вызов (данные) на месте? - person qballer; 09.08.2012
comment
Вы правы, обратный вызов (данные) будет вызван на месте, боюсь, это был плохой пример от меня. Если вы выполняете длительные операции ввода-вывода, вам лучше использовать эмиттер событий. После завершения операции ввода-вывода или генерации данных будет генерироваться событие complete, которое может содержать обратный вызов с заполненными данными. Дополнительную информацию об генераторах событий см. по ссылке. - person Mark Taylor; 09.08.2012
comment
Вы всегда можете изменить свой ответ. - person qballer; 09.08.2012
comment
Извините, хотя этот ответ отличный, он все еще неверен, поэтому я его не принял. - person qballer; 19.08.2012

Выбранный ответ является наиболее правильным, есть только одно незначительное изменение кода, а именно:

Измените эту функцию:

getDetail : function (id, callback) {
    var data = makeMyData(id);
    callback(data)
}

К тому, что:

getDetail : function (id, callback) {
    var data = makeMyData(id);
    setTimeout(callback, 0, data); 
}

Обновление 2019: чтобы соответствовать стандарту сообщества, я прервал обновление для нового ответа. Я использовал setTimeout, потому что хотел отложить обратный вызов в конец цикла событий. Другой вариант, который я использовал, был process.nextTick(), это помогло отложить обратный вызов до конца текущего обрабатываемого события. Например:

getDetail : function (id, callback) {
    var data = makeMyData(id);
    process.nextTick(((info)=> callback(info))(data)) 
}
person qballer    schedule 07.04.2019