Maison  >  Article  >  interface Web  >  Parlons des "réactions chimiques" qui se produiront lors de l'utilisation de wait dans les boucles JS

Parlons des "réactions chimiques" qui se produiront lors de l'utilisation de wait dans les boucles JS

藏色散人
藏色散人avant
2023-03-02 17:22:281691parcourir

Cet article vous apporte des connaissances pertinentes sur les boucles JavaScript. Il explique principalement comment utiliser wait dans les boucles js et l'analyse des résultats. Les amis intéressés devraient y jeter un œil.

Préface

Comment est née cette question ? Un jour, en apprenant les connaissances asynchrones, j'ai rencontré une question comme celle-ci : Utiliser Promise pour afficher une valeur dans un tableau toutes les secondes

const arr = [1, 2, 3]
arr.reduce((pre, cur) => {
  return pre.then(() => {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve(console.log(cur))
      }, 1000);
    })
  })
}, Promise.resolve())

Ce code est assez simple à comprendre, il équivaut à

Promise.resolve().then(() => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(console.log(1))
    }, 1000);
  })
}).then(() => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(console.log(2))
    }, 1000);
  })
}).then(() => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(console.log(3))
    }, 1000);
  })
})

Après avoir lu ceci, j'ai Je pensais que si je m'arrête pendant une seconde après avoir sorti la valeur dans une boucle, cela peut également être résolu, j'ai donc le code suivant

const arr = [1, 2, 3]
const sleep = (ms) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve()
    }, ms)
  })
}
for (let i = 0; i < arr.length; i++) {
  console.log(arr[i]);
  await sleep(1000)
}

Le résultat de l'impression est également conforme aux attentes. Ici, j'ai généré la première question : Non. 't wait doit-il être utilisé avec async ? Comment peut-il être utilisé seul ici ? (Si vous ne me croyez pas, essayez de mettre le code dans la console du navigateur)

Ensuite, j'ai changé for en forEach et j'ai constaté que l'effet n'était pas du tout obtenu. La deuxième question s'est posée : pourquoi wait in forEach a-t-il échoué ?

arr.forEach(async item => {
  console.log(item);
  await sleep(1000)
})

Avec ces deux questions, commencez à étudier et à chercher des réponses.

await dans la boucle for

Je me souviens qu'il y avait un dicton lors de l'apprentissage d'async/wait selon lequel wait ne pouvait être utilisé qu'avec async. En fait, cette phrase n'est pas fausse. Alors pourquoi puis-je écrire wait directement devant ? Parce que je l'écris directement dans la console du navigateur. Quand on écrit du code dans l'éditeur, il faut utiliser async

 <script>  
   const arr = [1, 2, 3]
   const sleep = (ms) => {
     return new Promise((resolve, reject) => {
       setTimeout(() => {
         resolve()
       }, ms)
     })
   }
   const logByOneSecond = async () => {
     for (let i = 0; i < arr.length; i++) {
       console.log(arr[i]);
       await sleep(1000)
     }
   }   
   logByOneSecond()
 </script>

Donc c'est une blague, haha, mais quand je ne le fais pas. comprends quelque chose, j'ai une autre façon de penser.

D'accord, comme mentionné ci-dessus, wait joue son rôle, permettant à JS d'attendre le résultat du traitement renvoyé par la promesse, puis de continuer à s'exécuter pendant...of, while est également possible

const logByForof = async () => {
  for (const item of arr) {
    console.log(item);
    await sleep(1000)
  }    
}
logByForof()
const logByWhile = async () => {
  let i = 0
  while (i !== arr.length) {
    await sleep(1000)
    console.log(arr[i]);
    i++
  }
}
logByWhile()

Les résultats sont également conforme aux attentes. Vous pouvez utiliser wait dans la boucle et obtenir l'effet

await dans la boucle forEach

Comme au début, l'effet attendu n'est pas obtenu dans forEach d'abord obtenir un résultat : async et wait in ; forEach n'est pas valide.

Ensuite, les explications que j'ai vues sont les suivantes

  • forEach en JavaScript ne prend pas en charge la sensibilisation aux promesses, ni async et wait, vous ne pouvez donc pas utiliser wait dans forEach.

  • map/forEach est utilisé en interne tout en étant combiné avec un rappel pour exécuter la fonction, wait n'attendra pas l'exécution du rappel

  • forEach ne prend en charge que le code synchrone

La deuxième façon de simplifier le pseudocode à l'avenir est la suivante

while(index < arr.length){
  callback(item, index)
}

map/forEach est une fonction de rappel d'exécution simple et ne gère pas les situations asynchrones. C'est-à-dire : map/forEach créera plusieurs fonctions de rappel en même temps, et plusieurs fonctions de rappel sont ajoutées avec leurs propres fonctions async et wait, comme indiqué ci-dessous

async ()=>{
  await sleep(1000); 
} 
async ()=>{ 
  await sleep(1000);
} 
async ()=>{ 
  await sleep(1000);
}

Chaque fonction est indépendante et les rappels des autres sont également indépendants de la demande ; est asynchrone, ils ne sont pas liés les uns aux autres et l'ordre ne peut pas être garanti

Résumé

Révision de l'utilisation de async/await dans les instructions de boucle Pour les boucles for ordinaires, toutes les attentes sont des appels en série Oui, vous pouvez. utilisez-le en toute confiance, y compris while, for-in, for-of, etc. ; cependant, les méthodes de tableau avec des rappels, telles que forEach, map, filter, reduction, etc., ont de nombreux effets secondaires, il est donc préférable de ne pas utilisez attendre.

【Apprentissage recommandé : Tutoriel avancé javascript

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer