1
votes

Pourquoi le programme nodejs se ferme-t-il lors de l'utilisation de Wait & EventEmitter?

Regardez ce code:

const { EventEmitter } = require('events');

class Trigger extends EventEmitter {
  constructor () {
    super();
  }

  run() {
    setTimeout(() => {
      this.emit('done');
    }, 1000);
  }

  waitUntilDone() {
    const this_ = this;
    return new Promise((resolve) => {
      this_.on('done', () => {
        resolve();
      });
    })
  }
}

async function main() {
  const tr = new Trigger();
  tr.run();
  console.log('run');
  // 如果监听的事件永远不会抛出,则此处程序会直接退出
  await tr.waitUntilDone().then(() => console.log('Promise done'));
  await tr.waitUntilDone().then(() => console.log('Promise done'));
  console.log('final done');
}

main();

Le programme se terminera à la seconde wait tr.waitUntilDone (). t ... , sans rien enregistré.

/ p>

Même le deuxième tr.waitUntilDone () ne peut jamais avoir l'événement, il devrait attendre indéfiniment, n'est-ce pas?


3 commentaires

Gardez à l'esprit que node.js n'attend pas que les promesses se résolvent avant de quitter. Il attend les minuteries (sauf si vous les .unref () ). Et rappelez-vous que main () renvoie une promesse immédiatement. Il n'est pas bloqué par wait .


@Sashi il sort tôt. Pingze, const this_ = this; n'est pas nécessaire puisque vous utilisez des fonctions fléchées.


Donc, je suppose qu'il est possible que node.js se termine entre le moment où le deuxième minuteur se déclenche et avant que votre deuxième gestionnaire .then () ne soit appelé, ignorant ainsi la journalisation final done .


3 Réponses :


0
votes

Si vous réinitialisez votre minuterie après la résolution de la première promesse, le programme ne se fermera pas tant que la dernière promesse ne sera pas résolue.

run
Promise done
Promise done
final done

Vous verrez le résultat:

async function main() {
    const tr = new Trigger();
    tr.run();
    console.log('run');

    await tr.waitUntilDone().then(() => { 
        console.log('Promise done'); 
        // Reset the timer (this will keep the program alive)
        tr.run();
    });
    await tr.waitUntilDone().then(() => console.log('Promise done'));
    console.log('final done');
}


0 commentaires

0
votes

Je pense que vous ne devez utiliser qu'une seule chose: Promise ou Async / Await.

1] Exemple Async / Await

function main() {
  const tr = new Trigger();
  console.log('run');
  tr.run();
  tr.waitUntilDone().then(() => console.log('Promise done'));
  tr.waitUntilDone().then(() => console.log('Promise done'));
  console.log('final done');
}

2] Exemple de promesse

async function main() {
    const tr = new Trigger();
    console.log('run');

    tr.run();
    await tr.waitUntilDone();
    console.log('Promise done');

    tr.run();
    await tr.waitUntilDone();
    console.log('Promise done')

    console.log('final done');
}

Votre expression " wait tr.waitUntilDone (). then (() => console.log ('Promise done')); " n'est pas correcte. Correct sera quelque chose comme ceci " wait tr.waitUntilDone (). Then (() => (console.log ('Promise done'), Promise.resolve ())); " ou " tr.waitUntilDone (). then (() => console.log ('Promise done')); "


0 commentaires

0
votes

Si vous voulez garder votre programme en vie pour toujours, vous pouvez l'ajouter en haut de votre code:

(function keepalive() {
    setTimeout(keepalive, 0x7FFFFFFF);
})();

En gros, tant qu'il y a un événement en attente, le runtime doit rester ouvert. J'espère que cela vous sera utile.


0 commentaires