105 votes

À l'aide de l'attendent à l'extérieur d'une fonction async

J'ai été de tenter de la chaîne deux async fonctions ensemble, parce que le premier avait un conditionnel paramètre de retour qui a provoqué la deuxième à exécuter, ou de quitter le module. Cependant, j'ai trouvé le comportement étrange je ne trouve pas dans les specs.

async function isInLobby() {
    //promise.all([chained methods here])
    let exit = false;
    if (someCondition) exit = true;
}

C'est une vision dénaturée extrait de mon code (vous pouvez voir l'intégralité du champ d'application ici), qui vérifie simplement si un joueur s'il est déjà dans un hall d'accueil, mais c'est hors de propos.

Ensuite, nous avons cette fonction async.

async function countPlayer() {
    const keyLength = await scardAsync(game);
    return keyLength;
}

Cette fonction n'a pas besoin de courir si exit === true.

J'ai essayé de faire

const inLobby = await isInLobby();

Cela, je l'espère, vous attendent pour des résultats, donc je peux l'utiliser inLobby pour exécuter conditionnellement countPlayer, cependant, j'ai reçu une erreur typeerror sans plus de détails.

Pourquoi ne pouvez-vous pas await un async fonction à l'extérieur de la portée de la fonction? Je sais que c'est un sucre promesse, de sorte qu'il doit être enchaînés en then mais pourquoi est-ce que, en countPlayer je peux attendre un autre promesse, mais à l'extérieur, je ne peux pas await isInLobby?

155voto

Il y a toujours cette de cours:

(async () => {
    await ...
})();

Ce qui fait un rapide fonction avec async où vous pouvez utiliser les attendent. Il vous permet d'économiser de la nécessité de faire de l'asynchrone en fonction de ce qui est génial! //crédits Silve2611

80voto

Andy Ray Points 4600

Niveau supérieur await n'est pas pris en charge. Il y a quelques discussions par le comité des normes sur les raisons de cette, comme cette Github question.

Il y a aussi un thinkpiece sur Github sur le pourquoi de haut niveau vous attendent est une mauvaise idée. Plus précisément, il suggère que si vous avez un code comme ceci:

// data.js
const data = await fetch( '/data.json' );
export default data;

Maintenant tout fichier que les importations en data.js ne s'exécute que lorsque l'extraction est terminée, de sorte que l'ensemble de votre module de chargement est maintenant bloqué. De ce fait, il est très difficile de raisonner sur l'app module de commande, car nous sommes habitués à haut niveau de l'exécution de Javascript de façon synchrone et prévisible. Si cela était permis, sachant quand une fonction est définie devient délicat.

Mon point de vue c'est que c'est une mauvaise pratique pour votre module pour avoir des effets secondaires, tout simplement en le chargeant. Cela signifie que les consommateurs de votre module va avoir des effets secondaires simplement en exigeant de votre module. Ce mal limites où votre module peut être utilisé. Un haut niveau d' await signifie probablement que vous êtes la lecture de certains de l'API ou de l'appel à certains services au moment du chargement. Au lieu de cela, vous devez juste l'exportation async fonctions que les consommateurs peuvent utiliser à leur propre rythme.

4voto

Viliam Simko Points 984

Encore mieux, c'est d'ajouter un point-virgule devant le bloc de code

;(async () => {
    await ...
})();

Cela empêche l'auto-formateur (par exemple, dans vscode) pour déplacer le premier parenthese à la fin de la ligne précédente.

Le problème peut être montré sur l'exemple suivant:

const add = x => y => x+y
const increment = add(1)
(async () => {
    await ...
})();

Sans le point-virgule, ce sera re-formaté comme:

const add = x => y => x+y
const increment = add(1)(async () => {
  await Promise(1)
})()

ce qui est évidemment faux, car il affecte la fonction async que l' y paramètre et tente d'appeler une fonction du résultat (qui est en fait une étrange chaîne '1async () => {...}')

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