web-dev-qa-db-fra.com

Comment effectuer une opération asynchrone à la sortie

J'ai essayé d'effectuer une opération asynchrone avant la fin de mon processus.

Dire "résilié" signifie toutes les possibilités de résiliation:

  • ctrl+c
  • Exception non interceptée
  • Crashes
  • Fin du code
  • N'importe quoi..

À ma connaissance, l'événement exit fait cela mais pour les opérations synchrones.

En lisant les documents Nodejs, j'ai trouvé l'événement beforeExit est pour les opérations asynchrones MAIS:

L'événement 'beforeExit' n'est pas émis pour les conditions provoquant une terminaison explicite, telles que l'appel de process.exit() ou des exceptions non interceptées.

L'événement 'beforeExit' ne doit pas être utilisé comme alternative à l'événement 'exit' sauf si l'intention est de planifier des travaux supplémentaires.

Aucune suggestion?

22
Kesem David

Vous pouvez intercepter les signaux et effectuer votre tâche asynchrone avant de quitter. Quelque chose comme ça appellera la fonction terminator () avant de quitter (même erreur javascript dans le code):

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.');
}

Ajouter le détail demandé dans le commentaire:

  • Les signaux expliqués à partir du nœud documentation , ce lien se réfère à la norme noms de signaux POSIX
  • Les signaux doivent être des chaînes. Cependant, j'ai vu que d'autres ont fait la vérification, il pourrait donc y avoir d'autres signaux inattendus que je ne connais pas. Je veux juste m'assurer avant d'appeler process.exit (). Je suppose que cela ne prend pas beaucoup de temps de toute façon.
  • pour db.close (), je suppose que cela dépend du pilote que vous utilisez. Que ce soit la synchronisation de l'async. Même si c'est asynchrone et que vous n'avez rien à faire après la fermeture de db, cela devrait être correct car async db.close () émet simplement un événement close et la boucle d'événement continuera à le traiter, que votre serveur se soit arrêté ou non.
13
Ben

Utilisation du crochet beforeExit

L'événement "beforeExit" est émis lorsque Node.js vide sa boucle d'événements et n'a aucun travail supplémentaire à planifier. Normalement, le processus Node.js se termine lorsqu'aucun travail n'est planifié, mais un écouteur enregistré sur l'événement "beforeExit" peut effectuer des appels asynchrones et entraîner ainsi la poursuite du processus Node.js.

process.on('beforeExit', async () => {
    await something()
    process.exit(0) // if you don't close yourself this will run forever
});
1
Sceat