79 votes

Fonction asynchrone sans attente en Javascript

J'ai deux fonctions a et b sont asynchrones, l'ancien sans await et, plus tard, avec await. Ils ont tous les deux journaux de quelque chose de la console et revenir undefined. Après l'appel, soit de la fonction que j'journal d'un autre message et regarde si le message est écrit avant ou après l'exécution du corps de la fonction.

function someMath() {
  for (let i = 0; i < 3000000; i++) { Math.sqrt(i**5) }
}

function timeout(n) {
   return new Promise(cb => setTimeout(cb, n))
}

// ------------------------------------------------- a (no await)
async function a() {
  someMath()
  console.log('in a (no await)')
}

// ---------------------------------------------------- b (await)
async function b() {
  await timeout(100)
  console.log('in b (await)')
}

clear.onclick = console.clear

aButton.onclick = function() {
  a()
  console.log('after a (no await) call')
}

bButton.onclick = function() {
  b()
  console.log('after b (await) call')
}
<button id="aButton">test without await</button>
<button id="bButton">test with await</button>
<button id="clear">clear console</button>

Si vous lancez le test sans await la fonction semble fonctionner comme si c'était synchrone. Mais avec await, le message sont inversées comme la fonction est exécutée de manière asynchrone.

Donc ma question est: comment exécuter javascript async de fonctions de n await mot-clé est présent?


Véritable cas d'utilisation: j'ai un await mot-clé qui est conditionnaly exécuté, et j'ai besoin de savoir si la fonction est exécutée de manière synchrone ou non afin de rendre mon élément:

async function initializeComponent(stuff) {
   if (stuff === undefined)
      stuff = await getStuff()
   // initialize

   if (/* context has been blocked */)
       renderComponent() // render again if stuff had to be loaded
}

initializeComponent()
renderComponent()

P. S: le titre a le javascript mot-clé pour éviter la confusion avec les mêmes questions dans d'autres langues (j'.e en Utilisant asynchrone sans attendre)

70voto

Karim Points 4349

à partir de mozilla doc:

Une fonction async peut contenir une expression await, qui met en pause le l'exécution de la fonction async et attend la Promesse de l' la résolution, et reprend ensuite l'asynchrone en fonction de l'exécution et de la renvoie la valeur résolue.

Comme vous l'avez supposé, si aucune attendent est présent à l'exécution n'est pas suspendue et votre code sera exécuté de manière synchrone.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function#Description

37voto

NAVIN Points 1849

Tout est synchrone jusqu'à ce qu'un Javascript asynchrone fonction est exécutée. En utilisant asynchrone attendent await est asynchrone et tout ce qui suit vous attendent, est placé dans la file d'attente des événements. Semblable à l' .then().

Pour mieux expliquer prenez cet exemple:

function main() {
  return new Promise( resolve => {
    console.log(3);
    resolve(4);
    console.log(5);
  });
}

async function f(){
    console.log(2);
    let r = await main();
    console.log(r);
}

console.log(1);
f();
console.log(6);

En tant que await est asynchrone et le reste tous est synchrone, y compris la promesse donc la sortie est

1
2
3
5
6
// Async happened, await for main()
4

Un comportement similaire de main() est sans promesse de trop:

function main() {
    console.log(3);
    return 4;
}

async function f(){
    console.log(2);
    let r = await main();
    console.log(r);
}

console.log(1);
f();
console.log(5);

Sortie:

1
2
3
5
// Asynchronous happened, await for main()
4

Simplement en enlevant await fera tout async fonction synchrone qui il est.

function main() {
    console.log(3);
    return 4;
}

async function f(){
    console.log(2);
    let r = main();
    console.log(r);
}

console.log(1);
f();
console.log(5);

Sortie:

1
2
3
4
5

23voto

Barmar Points 135986

La fonction est exécutée de la même manière avec ou sans await . Ce que await fait est automatiquement d'attendre que la promesse retournée par la fonction soit résolue.

 await timeout(1000);
more code here;
 

est à peu près équivalent à:

 timeout(1000).then(function() {
    more code here;
});
 

La déclaration async function fait simplement que la fonction retourne automatiquement une promesse qui est résolue lorsque la fonction revient.

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