Home > Web Front-end > JS Tutorial > body text

Let's talk about what 'chemical reactions” will occur when using await in JS loops

藏色散人
Release: 2023-03-02 19:56:11
forward
1717 people have browsed it

This article brings you relevant knowledge about JavaScript loops. It mainly talks about how to use await in js loops and result analysis. Friends who are interested should take a look at it. I hope it will be useful to everyone. help.

Preface

How did this question arise? One day, while learning about asynchronous knowledge, I encountered this question: Use Promise to output a value in the array every second

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())
Copy after login

Then this code is quite easy to understand, equivalent to

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);
  })
})
Copy after login

After reading this, I was thinking that if I stopped for one second after each output value in a loop, it could also be solved, so I came up with the following code

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)
}
Copy after login

The printing result is also consistent As expected, I had my first question here: Doesn't await need to be used with async? How can it be used alone here? (If you don’t believe me, try putting the code in the browser console)

Then I changed for to forEach, and found that the effect was not achieved at all. The second question arose: Why did await in forEach fail?

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

With these two questions, start studying and looking for answers.

await in the for loop

I remember there was a sentence when I was learning async/await, await can only be used with async, in fact, this sentence There is nothing wrong with that. Then why can I write await directly in the front? Because I write it directly in the browser console. When we write code in the editor, we must use an 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>
Copy after login

, so this is a joke. , haha, but when I encounter something I don’t understand, I have another way to think.

Okay, as mentioned above, await does play its role, allowing JS to wait until the processing result returned by promise, and then continue to execute; then for...of, while can also be

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

The result is also in line with expectations. You can use await in the loop to achieve the effect

await in the forEach loop

As at the beginning, in There is no expected effect in forEach; first of all, we get a result: async and await in forEach are invalid.

The explanations I saw are as follows

  • forEach in JavaScript does not support promise awareness, nor does it support async and await, so you cannot use await in forEach .

  • map/forEach internally uses while combined with callback to execute functions. await will not wait for the execution of callback.

  • forEach only supports synchronous code

The second statement is to simplify the pseudocode in the future, as follows

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

map/forEach is a simple execution callback function and will not handle asynchronous situations. That is: map/forEach will create multiple callback functions at the same time. Multiple callback functions are added with their own async and await, as follows

async ()=>{
  await sleep(1000); 
} 
async ()=>{ 
  await sleep(1000);
} 
async ()=>{ 
  await sleep(1000);
}
Copy after login

Each function is independent of each other, and each other's callbacks are also independent. ;The requests are asynchronous and have no correlation with each other, so the order cannot be guaranteed

Summary

Reviewed the use of async/await in loop statements , for ordinary for-loops, all awaits are called serially and can be used with confidence, including while, for-in, for-of, etc.; but in array methods with callbacks, such as forEach, map, filter, reduce, etc., have many side effects, so it is best not to use await.

[Recommended learning: javascript advanced tutorial]

The above is the detailed content of Let's talk about what 'chemical reactions” will occur when using await in JS loops. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:juejin.im
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!