2016-11-13 2 views
6

Я пытаюсь выполнить асинхронную операцию до завершения моего процесса.Как выполнить операцию async при выходе

поговорке 'прекращено' Я имею в виду все возможности прекращения:

  • ctrl+c
  • неперехваченным исключение
  • Crashes
  • Конец кода
  • Anything ..

Для мои знания exit это делает, но для синхронных операций.

Читая документы Nodejs я нашел beforeExit события для операций асинхронных НО:

события «beforeExit» не излучается для условий, вызывающим явного прекращение, например, вызов process.exit() или пойманных исключений.

«beforeExit» не следует использовать в качестве альтернативы событию «выход», если только не намерено планировать дополнительную работу.

Любые предложения?

+1

Как насчет того, чтобы поместить весь код в отдельный файл (например, afterExit.js) и когда произойдет событие выхода, запустите 'require ('child_process'). Exec ('node afterExit.js');', это просто мысль, хотя – Molda

+0

@Molda эй снова, я некоторое время оставил эту проблему и теперь вернулся к работе, решил использовать и внешний скрипт, который будет выполнен, как вы предложили, будет простым решением, но я столкнулся с непониманием того, как пройти любой переменные для этого скрипта, так как этот код «afterExit» зависит от состояния родителя, любая помощь будет высоко оценена! –

+0

Вы можете передать некоторые переменные в качестве параметров, например. 'exec ('node afterExit.js some_param some_other_param');' и затем получить доступ к 'process.args' или создать файл json с требуемыми данными и передать путь к этому файлу в ваш скрипт и загрузить этот файл из afterExit.js – Molda

ответ

4

Вы можете захватить сигналы и выполнить свою асинхронную задачу перед выходом. Нечто подобное будет вызывать терминатор() функцию до выхода (даже Javascript ошибки в коде):

process.on('exit', function() { 
    // Do some cleanup such as close db 
    if (db) { 
     db.close(); 
    } 
}); 

// catching signals and do something before exit 
['SIGHUP', 'SIGINT', 'SIGQUIT', 'SIGILL', 'SIGTRAP', 'SIGABRT', 
    'SIGBUS', 'SIGFPE', 'SIGUSR1', 'SIGSEGV', 'SIGUSR2', 'SIGTERM' 
].forEach(function (sig) { 
    process.on(sig, function() { 
     terminator(sig); 
     console.log('signal: ' + sig); 
    }); 
}); 

function terminator(sig) { 
    if (typeof sig === "string") { 
     // call your async task here and then call process.exit() after async task is done 
     myAsyncTaskBeforeExit(function() { 
      console.log('Received %s - terminating server app ...', sig); 
      process.exit(1); 
     }); 
    } 
    console.log('Node server stopped.'); 
} 

Добавить деталь запрашиваемой в комментарии:

  • Сигналы объясняются от узла documentation, эта ссылка относится к стандартному POSIX signal names
  • Сигналы должны быть строковыми. Тем не менее, я видел, что другие сделали чек, поэтому могут появиться и другие неожиданные сигналы, о которых я не знаю. Просто хочу убедиться перед вызовом process.exit(). Я полагаю, что в любом случае не требуется много времени для проверки.
  • для db.close(), я думаю, это зависит от используемого вами драйвера. Является ли это синхронизацией async. Даже если это асинхронно, и вам не нужно ничего делать после закрытия db, тогда это должно быть хорошо, потому что async db.close() просто испускает закрытое событие, и цикл событий будет продолжать обрабатывать его независимо от того, вышел ли ваш сервер или нет.
+0

Эй, Бен, спасибо за Ваш ответ. Не могли бы вы дать несколько пояснений по поводу этого кода? сигналы, знакомые с «SIGINT» и «exit», какие у других? также, почему вы проверяете, является ли 'sig'' строкой'? и предполагая, что 'db.close' is async, он не будет закончен там правильно? –

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