async
is relatively simple to use with await
. But things get a little more complicated when you try to use await
inside a loop.
In this article, share some issues worth noting when using await
in if loops.
Prepare an example
For this post, let’s say you want to get the number of fruits from a fruit basket.
const fruitBasket = { apple: 27, grape: 0, pear: 14 };
You want to get the quantity of each fruit from fruitBasket
. To get the number of fruits, you can use the getNumFruit
function.
const getNumFruit = fruit => { return fruitBasket[fruit]; }; const numApples = getNumFruit('apple'); console.log(numApples); //27
Now, assuming fruitBasket
is obtained from the server, here we use setTimeout
to simulate.
const sleep = ms => { return new Promise(resolve => setTimeout(resolve, ms)) }; const getNumFruie = fruit => { return sleep(1000).then(v => fruitBasket[fruit]); }; getNumFruit("apple").then(num => console.log(num)); // 27
Finally, suppose you want to use await
and getNumFruit
to get the number of each fruit in an asynchronous function.
const control = async _ => { console.log('Start') const numApples = await getNumFruit('apple'); console.log(numApples); const numGrapes = await getNumFruit('grape'); console.log(numGrapes); const numPears = await getNumFruit('pear'); console.log(numPears); console.log('End') }
Use await in a for loop
First define an array to store fruits:
const fruitsToGet = [“apple”, “grape”, “pear”];
Loop Traverse this array:
const forLoop = async _ => { console.log('Start'); for (let index = 0; index <p>In the <code>for</code> loop, use <code>getNumFruit</code> to get the number of each fruit and print the number to the console. </p><p>Since <code>getNumFruit</code> returns a <code>promise</code>, we use <code>await</code> to wait for the result to be returned and print it. </p><pre class="brush:php;toolbar:false">const forLoop = async _ => { console.log('start'); for (let index = 0; index <p>When using <code>await</code>, you want JavaScript to pause execution until the promise returns the processing result. This means that the <code>await</code> in the <code>for</code> loop should be executed sequentially. </p><p>The results are as you would expect. </p><pre class="brush:php;toolbar:false">“Start”; “Apple: 27”; “Grape: 0”; “Pear: 14”; “End”;
This behavior applies to most loops (such as while
and for-of
loops)…
But it cannot handle loops that require callbacks, such as forEach
, map
, filter
, and reduce
. In the next few sections, we'll examine how await
affects forEach
, map, and filter
.
Use await in the forEach loop
First, use forEach
to traverse the array.
const forEach = _ => { console.log('start'); fruitsToGet.forEach(fruit => { //... }) console.log('End') }
Next, we will try to get the number of fruits using getNumFruit
. (Note the async
keyword in the callback function. We need this async
keyword because await
is in the callback function).
const forEachLoop = _ => { console.log('Start'); fruitsToGet.forEach(async fruit => { const numFruit = await getNumFruit(fruit); console.log(numFruit) }); console.log('End') }
I expected the console to print the following:
“Start”; “27”; “0”; “14”; “End”;
But the actual result is different. Before waiting for the return result in the forEach
loop, JavaScript first executes console.log('End').
The actual console print is as follows:
‘Start’ ‘End’ ‘27’ ‘0’ ‘14’
forEach
in JavaScript does not support promise awareness, but also supports async
and await
, so await
cannot be used in forEach
.
Use await in map
If you use await
in map
, map
always Returns an array of promise
, because asynchronous functions always return promise
.
const mapLoop = async _ => { console.log('Start') const numFruits = await fruitsToGet.map(async fruit => { const numFruit = await getNumFruit(fruit); return numFruit; }) console.log(numFruits); console.log('End') } “Start”; “[Promise, Promise, Promise]”; “End”;
If you use await
in map
, map
always returns promises
, you must wait for the promises
array to be processed. Or do this via await Promise.all(arrayOfPromises)
.
const mapLoop = async _ => { console.log('Start'); const promises = fruitsToGet.map(async fruit => { const numFruit = await getNumFruit(fruit); return numFruit; }); const numFruits = await Promise.all(promises); console.log(numFruits); console.log('End') }
The running results are as follows:
If you like, you can process the return value in promise
, and the parsed value will be returned value.
const mapLoop = _ => { // ... const promises = fruitsToGet.map(async fruit => { const numFruit = await getNumFruit(fruit); return numFruit + 100 }) // ... } “Start”; “[127, 100, 114]”; “End”;
Using await in a filter loop
When you use filter
, you want to filter the array with specific results. Suppose you filter an array whose number is greater than 20.
If you use filter
normally (without await), as follows:
const filterLoop = _ => { console.log('Start') const moreThan20 = fruitsToGet.filter(async fruit => { const numFruit = await fruitBasket[fruit] return numFruit > 20 }) console.log(moreThan20) console.log('END') }
Running results
Start ["apple"] END
filter
await
won't work the same way. In fact, it doesn't work at all.
const filterLoop = async _ => { console.log('Start') const moreThan20 = await fruitsToGet.filter(async fruit => { const numFruit = fruitBasket[fruit] return numFruit > 20 }) console.log(moreThan20) console.log('END') } // 打印结果 Start ["apple", "grape", "pear"] END
Why does this happen?
When using await
in a filter
callback, The callback is always a promise
. Since promise
is always true, all items in the array pass through filter
. Use the following code in filter
await
class
const filtered = array.filter(true);
在filter
使用 await
正确的三个步骤
- 使用
map
返回一个promise 数组 - 使用
await
等待处理结果 - 使用
filter
对返回的结果进行处理
const filterLoop = async _ => { console.log('Start'); const promises = await fruitsToGet.map(fruit => getNumFruit(fruit)); const numFruits = await Promise.all(promises); const moreThan20 = fruitsToGet.filter((fruit, index) => { const numFruit = numFruits[index]; return numFruit > 20; }) console.log(moreThan20); console.log('End') }
在 reduce 循环中使用 await
如果想要计算 fruitBastet
中的水果总数。 通常,你可以使用reduce
循环遍历数组并将数字相加。
const reduceLoop = _ => { console.log('Start'); const sum = fruitsToGet.reduce((sum, fruit) => { const numFruit = fruitBasket[fruit]; return sum + numFruit; }, 0) console.log(sum) console.log('End') }
运行结果:
当你在 reduce
中使用await
时,结果会变得非常混乱。
const reduceLoop = async _ => { console.log('Start'); const sum = await fruitsToGet.reduce(async (sum, fruit) => { const numFruit = await fruitBasket[fruit]; return sum + numFruit; }, 0) console.log(sum) console.log('End') }
[object Promise]14
是什么 鬼??
剖析这一点很有趣。
- 在第一次遍历中,
sum
为0
。numFruit
是27
(通过getNumFruit(apple)
的得到的值),0 + 27 = 27
。 - 在第二次遍历中,
sum
是一个promise
。 (为什么?因为异步函数总是返回promises
!)numFruit
是0
.promise 无法正常添加到对象,因此JavaScript将其转换为[object Promise]
字符串。[object Promise] + 0
是object Promise] 0
。 - 在第三次遍历中,
sum
也是一个promise
。numFruit
是14
.[object Promise] + 14
是[object Promise] 14
。
解开谜团!
这意味着,你可以在reduce
回调中使用await
,但是你必须记住先等待累加器!
const reduceLoop = async _ => { console.log('Start'); const sum = await fruitsToGet.reduce(async (promisedSum, fruit) => { const sum = await promisedSum; const numFruit = await fruitBasket[fruit]; return sum + numFruit; }, 0) console.log(sum) console.log('End') }
但是从上图中看到的那样,await
操作都需要很长时间。 发生这种情况是因为reduceLoop
需要等待每次遍历完成promisedSum
。
有一种方法可以加速reduce
循环,如果你在等待promisedSum之前先等待getNumFruits()
,那么reduceLoop
只需要一秒钟即可完成:
const reduceLoop = async _ => { console.log('Start'); const sum = await fruitsToGet.reduce(async (promisedSum, fruit) => { const numFruit = await fruitBasket[fruit]; const sum = await promisedSum; return sum + numFruit; }, 0) console.log(sum) console.log('End') }
这是因为reduce
可以在等待循环的下一个迭代之前触发所有三个getNumFruit
promise。然而,这个方法有点令人困惑,因为你必须注意等待的顺序。
在reduce中使用wait最简单(也是最有效)的方法是
- 使用
map
返回一个promise 数组 - 使用
await
等待处理结果 - 使用
reduce
对返回的结果进行处理const reduceLoop = async _ => {
console.log('Start');const promises = fruitsToGet.map(getNumFruit);
const numFruits = await Promise.all(promises);
const sum = numFruits.reduce((sum, fruit) => sum + fruit);console.log(sum)
console.log('End')
}
这个版本易于阅读和理解,需要一秒钟来计算水果总数。
从上面看出来什么
- 如果你想连续执行
await
调用,请使用for
循环(或任何没有回调的循环)。 - 永远不要和
forEach
一起使用await
,而是使用for
循环(或任何没有回调的循环)。 - 不要在
filter
和reduce
中使用await
,如果需要,先用map
进一步骤处理,然后在使用filter
和reduce
进行处理。
原文地址:https://medium.com/free-code-camp/javascript-async-and-await-in-loops-30ecc5fb3939
更多编程相关知识,请访问:编程学习网站!!
The above is the detailed content of How to use async/await in JavaScript loops? What needs attention?. For more information, please follow other related articles on the PHP Chinese website!

The main difference between Python and JavaScript is the type system and application scenarios. 1. Python uses dynamic types, suitable for scientific computing and data analysis. 2. JavaScript adopts weak types and is widely used in front-end and full-stack development. The two have their own advantages in asynchronous programming and performance optimization, and should be decided according to project requirements when choosing.

Whether to choose Python or JavaScript depends on the project type: 1) Choose Python for data science and automation tasks; 2) Choose JavaScript for front-end and full-stack development. Python is favored for its powerful library in data processing and automation, while JavaScript is indispensable for its advantages in web interaction and full-stack development.

Python and JavaScript each have their own advantages, and the choice depends on project needs and personal preferences. 1. Python is easy to learn, with concise syntax, suitable for data science and back-end development, but has a slow execution speed. 2. JavaScript is everywhere in front-end development and has strong asynchronous programming capabilities. Node.js makes it suitable for full-stack development, but the syntax may be complex and error-prone.

JavaScriptisnotbuiltonCorC ;it'saninterpretedlanguagethatrunsonenginesoftenwritteninC .1)JavaScriptwasdesignedasalightweight,interpretedlanguageforwebbrowsers.2)EnginesevolvedfromsimpleinterpreterstoJITcompilers,typicallyinC ,improvingperformance.

JavaScript can be used for front-end and back-end development. The front-end enhances the user experience through DOM operations, and the back-end handles server tasks through Node.js. 1. Front-end example: Change the content of the web page text. 2. Backend example: Create a Node.js server.

Choosing Python or JavaScript should be based on career development, learning curve and ecosystem: 1) Career development: Python is suitable for data science and back-end development, while JavaScript is suitable for front-end and full-stack development. 2) Learning curve: Python syntax is concise and suitable for beginners; JavaScript syntax is flexible. 3) Ecosystem: Python has rich scientific computing libraries, and JavaScript has a powerful front-end framework.

The power of the JavaScript framework lies in simplifying development, improving user experience and application performance. When choosing a framework, consider: 1. Project size and complexity, 2. Team experience, 3. Ecosystem and community support.

Introduction I know you may find it strange, what exactly does JavaScript, C and browser have to do? They seem to be unrelated, but in fact, they play a very important role in modern web development. Today we will discuss the close connection between these three. Through this article, you will learn how JavaScript runs in the browser, the role of C in the browser engine, and how they work together to drive rendering and interaction of web pages. We all know the relationship between JavaScript and browser. JavaScript is the core language of front-end development. It runs directly in the browser, making web pages vivid and interesting. Have you ever wondered why JavaScr


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Dreamweaver Mac version
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

EditPlus Chinese cracked version
Small size, syntax highlighting, does not support code prompt function

MinGW - Minimalist GNU for Windows
This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.
