@kirick

Как узнать о завершении выполнения кода модуля в Node.JS?

Вот, например, у нас пример некого асинхронного кода в файле test.js:
console.log('start')
setTimeout(function(){
  console.log('end.')
}, 2000)

Если выполнить его как node test.js, то командная строка справится с асинхронностью и вернётся в режим ввода команд только через 2 секунды.

Теперь другой пример. Файл some_module.js (извиняюсь, что так много кода, пытался детально расписать кейс):
module.exports = function(){
  var self = this
  self.log = ''
  self.write = function(t){ log += t + '\n' }
  self.some_method = function(){
    var fs = require('fs')
    fs.readFile('some_file.txt', function(err, content){
      if(err){
        self.write(err.stack)
        return
      }
      self.write('start async operation...')
      // любая асинхронная операция
      // например, отправка содержимого файла другому серверу
      setTimeout(function(){
        self.write('completed')
      }, 2000)
    })
  }
}

и файл test.js:
require('http').createServer(function(req, res){
  var some_module = new ( require('some_module.js') )()
  some_module.some_method()
  // вот тут проблема
  // нужно отправить ответ, когда выполнение some_method() завершилось
  // и some_module.log больше заполняться не будет
  res.write(some_module.log).end()
}).listen(80)

Конечно, можно приписывать в нужных местах в функции some_method некий коллбэк, который будет передан из test.js (что-то вроде self.end()), тогда проблема решается (сейчас я так и делаю). Но это не изящное решение проблемы, ведь self.end() будет дублировать по смыслу оператор return. Например, у меня таких (some_module.js) модулей около пятидесяти и оповещать родительский скрипт везде вручную меня совсем не устраивает.

Вот откуда взялось моё недовольство (там более подробное описание проблемы, тут я описал попроще). Код каждой веб-страницы у меня является отдельным модулем, и везде писать njs.exit() — не ок.

Вот тут и появляется вопрос — есть ли какое-либо системный (или не очень) модуль Node.JS, который может меня оповестить, когда выполнение кода моего модуля прекратилось.
Я знаю про модуль process, но плодить процессы на каждый запрос к серверу не в стиле Node.JS.
  • Вопрос задан
  • 508 просмотров
Пригласить эксперта
Ответы на вопрос 2
Если уж вы серьезно собираетесь писать PHP подобный сервер, то мой вам совет почитайте про vm модуль, он бы вам пригодился.

Но честно говоря вы создали себе проблему на пустом месте, потому что сменили язык программирования, но не сменили идеологию мышления.
Ответ написан
standy
@standy
Воспользуйтесь промисами, они решают эту проблему
Если some_method будет возвращать Promise, то можно написать так:
some_module.some_method()
.then(function() {
  res.write(some_module.log).end()
})


Можно углубиться в es6 и воспользоваться, например, генераторами:
yield some_module.some_method();
// выполнение продолжится только когда some_method разрешится
res.write(some_module.log).end();
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы