首先来看一个比较简单的问题,我们想实现的每隔1s输出下列数组的值,看下错误写法:
let arr = [1, 2, 3, 4, 5]
arr.forEach((item) => {
setTimeout(() => {
console.log(item)
},1000)
})
会在1s后同时输出1、2、3、4、5,setTimeout定时根本就没有起作用,这是因为:单线程的js在操作时,对于这种异步操作,会先将其进入异步队列,等到整个for循环执行结束后,并且到达了异步执行条件,才会开始执行,setTimeout是写在for循环中的,这5次调用均是在for循环结束后进行的,所以会在异步条件1s到达时,同时执行。
为了避免这种问题,提供几种解决方法。
一般情况下,可以用递归实现,如下:
let arr = [1, 2, 3, 4, 5]
let index = 0
function f() {
if (index >= arr.length) {
console.log('all Done')
} else {
console.log(index)
index ++
setTimeout(function () {
f()
}, 5000)
}
}
f()
使用async、await实现,可以如下写法:
let arr = [1, 2, 3, 4, 5]
let asyncF = function(i) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
console.log(i);
resolve();
}, 1000);
});
}
let f = async function() {
for (let i = 0; i< arr.length; i++) {
await asyncF(i);
}
}
f()
网友评论