166 votes

Comment "attendre" un rappel pour revenir?

Lors de l'utilisation d'un rappel simple comme dans l'exemple ci-dessous:

 test() {
  api.on( 'someEvent', function( response ) {
    return response;
  });
}
 

Comment la fonction peut-elle être modifiée pour utiliser asynchrone / wait? Spécifiquement, en supposant que «someEvent» soit garanti d'être appelé une fois et une fois seulement, j'aimerais que le test de fonction soit une fonction asynchrone qui ne retourne pas tant que le rappel n'a pas été exécuté, tel que:

 async test() {
  return await api.on( 'someEvent' );
}
 

233voto

Second Rikudo Points 59550

async/await n'est pas de la magie. Un async fonction est une fonction qui permet de déballer des Promesses pour vous, alors vous aurez besoin d' api.on() de retour d'une Promesse pour que cela fonctionne. Quelque chose comme ceci:

function apiOn(event) {
  return new Promise(resolve => {
    api.on(event, response => resolve(response));
  });
}

Alors

async function test() {
  return await apiOn( 'someEvent' ); // await is actually optional here
                                      // you'd return a Promise either way.
}

Mais c'est un mensonge de trop, parce que async fonctions renvoient également Promesses eux-mêmes, de sorte que vous ne vont pas à réellement obtenir la valeur de test(), mais plutôt, une Promesse pour une valeur, que vous pouvez utiliser comme ceci:

async function whatever() {
  // snip
  const response = await test();
  // use response here
  // snip
}

14voto

ErikD Points 1

C'est ennuyeux qu'il n'y a pas une solution simple et efficace, et à l'habillage return new Promise(...) est moche, mais j'ai trouvé un ok de travail autour de l'aide d' util.promisify (en fait, elle aussi un peu le même emballage, juste l'air plus sympa).

function voidFunction(someArgs, callback) {
  api.onActionwhichTakesTime(someMoreArgs, (response_we_need) => {
    callback(null, response_we_need);
  });
}

La fonction ci-dessus ne retourne rien, et pourtant. Nous pouvons le faire en retour un Promise de la response adoptée en callback en faisant:

const util = require('util');

const asyncFunction = util.promisify(voidFunction);

Maintenant, nous pouvons réellement await le callback.

async function test() {
  return await asyncFunction(args);
}

Certaines règles lors de l'utilisation d' util.promisify

  • L' callback doit être le dernier argument de la fonction qui va être promisify
  • Le soi-disant fonction de rappel doit être sous la forme (err, res) => {...}

La chose drôle est que nous ne pouvons jamais spécifiquement écrire ce qui est de l' callback est en réalité.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X