1. The introduction
There are many problems about asynchronous realization of front-end interview, with similar centers, different focuses and varying difficulties. Details abound. The problem with implementing await in common loops is that it is possible to use await in common loops
async function test() { let arr = [6, 5, /* arr[6,5,8] */ console.log(' end ')} function handle(x) {return new Promise((resolve, reject) => { setTimeout(() => { resolve(x) }, 2000 * x) }) } test()Copy the code
2. The test
1. What is the wrong answer? Using it does not make the output output in the order of the array elements, the order of the numbers ascending according to the time set by the Promise’s setTimeOut. Sometimes multiple tasks in a program need to be executed in a certain order, but the tasks take different times. This treatment can create problems.
arr.forEach(async item => {
const res = await handle(item)
console.log(res)
})
Copy the code
The output is as follows
2. Cause of the problem: The problem can be found in the underlying implementation of forEach. ForEach takes it and executes it directly, which makes it unable to guarantee the order in which asynchronous tasks are executed. Since the loop takes much less time to execute once than the time-consuming task in the Promise, the time-consuming numeric subscript is judged first, the callback function is executed first, and output first
for (var i = 0; i < length; i++) { if (i in array) { var element = array[i]; callback(element, i, array); The callback function takes three arguments, the current value, the subscript, and the array name, to execute}}Copy the code
3. The output is what we expected
async function test() {
let arr = [6, 5, 8]
for(const item of arr) {
const res = await handle(item)
console.log(res)
}
console.log('结束')
}
Copy the code
Iterator Iterator Iterator group, native with [Symbol. Iterator] attribute data type for the iterable data type. Such as groups, class arrays (e.g. Arguments, NodeList), sets, and maps. As you can see, symbol. iterator adds additional attributes, value and done, to each item of the array; The latter is central to ensuring success. Done, along with the iterator’s next() method, determines whether to execute the next task of the array.
let arr = [6, 5, 8]; // let iterator = arr[symbol.iterator](); console.log(iterator.next()); console.log(iterator.next()); console.log(iterator.next()); console.log(iterator.next()); // {value: 4, done: false} // {value: 2, done: false} // {value: 1, done: false} // {value: undefined, done: true}Copy the code
So for of is equivalent to the following code
async function test() { let arr = [6, 5, 8] let iterator = arr[Symbol.iterator](); let res = iterator.next(); while(! Res.done) {// Let value = res.value; console.log(value); await handle(value); res = iterater.next(); } console.log(' end ')} // Start the next task only when the value is await handle.Copy the code
for in
Index is a string number that cannot be directly used for geometric operations. 3. Using for in iterates through all enumerable properties of an array, including stereotypes. So for in is better for traversing objects, not for in groups. But it can also serve a purpose. Just change it up a little bit. The principle is similar to for of.
for(const item in arr) {
const res = await handle(arr[item])
console.log(res)
}
Copy the code
3. Summary
This question is more a test of our understanding of the underlying implementation of various loops, but the key is the contradiction between how long asynchronous tasks take and the correct order of execution. In the interview we need to grasp the contradiction first, along the right train of thought.