JS中For循环中嵌套setTimeout()方法的执行顺序
function time() {
for(var i= 0;i<5;i++){
setTimeout(function () {
console.log(i);
},1000)
}
}
time();
setTimeOut() 是一个异步函数。
JS的执行机制是单线程环境。
JS遇到异步函数的时候,会把异步函数插入到队列中等待。
由于setTimeOut()设置了一秒后才执行,所以插入的队列位置是一秒后。
用代码表示的话就是我们最开始设想的流程是这样的:
for(i=0) ——> console.log(0) ——> for(i=1) ——> console.log(1) ——> for(i=2) ——> console.log(2) ——> for(i=3) ——> console.log(3) ——> for(i=4) ——> console.log(4) ——> for(i=5) ——> 执行结束
但是在实际中的流程是这样的:
for(i=0) ——> for(i=1) ——> for(i=2) for(i=3) ——> for(i=4) ——> for(i=5)ps:(这段循环都在一秒内完成了)——> console.log(5) ——> console.log(5) ——> console.log(5) ——> console.log(5) ——> console.log(5) ——> 执行完成
解决方法
闭包,立即执行的函数表达式(IIFE)
for (var i = 0; i < 5; i++) {
(function (i) {
setTimeout(function () {
console.log(i);
}, 1000 * i)
})(i) //这里使用闭包
}
立即执行函数是基于匿名函数实现的,也没有函数名,会在定义后立即执行; 闭包是有权访问另一个函数作用域中的变量的函数。 匿名函数、立即执行函数只要满足 有权访问另一个函数作用域中的变量 这一个条件,就成了闭包。
使用let,块级作用域
for (let i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i)
}, 1000 * i)
}
JS中For循环中嵌套setTimeout(),延迟时间是0呢?
for (var i = 0; i <10; i++) {
setTimeout(function() { // 同步注册回调函数到 异步的 宏任务队列。
console.log(i) // 执行此代码时,同步代码for循环已经执行完成
}, 0)
}
setTimeout(function(),0) 也不是立马执行(特别是有耗时代码在前),这是因为 js 是单线程的,有一个事件队列机制,setTimeout 和 setInterval 的回调会到了延迟时间塞入事件队列中,排队执行。
setTimeout在若干毫秒后执行一个函数,并且是在for循环结束后。 for循环结束后,i的值为10。 所以当函数被调用的时候,它会打印出 10,其实道理是一样的。
setTimeout :延时 delay 毫秒之后,啥也不管,直接将回调函数加入事件队列。
setInterval :延时 delay 毫秒之后,先看看事件队列中是否存在还没有执行的回调函数( setInterval 的回调函数),如果存在,就不要再往事件队列里加入回调函数了。
JS的运行机制
console.log("DIYXI");
setTimeout(function() {
console.log("定时器");
}, 0);
Promise.resolve()
.then(function() {
console.log("promise1");
})
.then(function() {
console.log("promise2");
});
console.log("blog.diyxi.top");
#输出结果为
DIYXI
blog.diyxi.top
promise1
promise2
定时器
主线程 > 同步任务 > 微任务 > 宏任务