比如:
for(var i=0;i<10;i++){
setTimeout(function() {
console.log(i);
}, 0);
}
我一直以为这里是因为闭包才输出10个10,后来面试官告诉我是因为异步,为什么是异步呢?
比如:
for(var i=0;i<10;i++){
setTimeout(function() {
console.log(i);
}, 0);
}
我一直以为这里是因为闭包才输出10个10,后来面试官告诉我是因为异步,为什么是异步呢?
setTimeout
的延迟不是绝对精确的;setTimeout
的意思是传递一个函数,延迟一段时候把该函数添加到队列当中,并不是立即执行;
所以说如果当前正在运行的代码没有运行完,即使延迟的时间已经过完,该函数会等待到函数队列中前面所有的函数运行完毕之后才会运行;也就是说所有传递给setTimeout
的回调方法都会在整个环境下的所有代码运行完毕之后执行;
setTimeout(function(){
console.log("here");
}, 0);
var i = 0;
//具体数值根据你的计算机CPU来决定,达到延迟效果就好
while (i < 3000000000) {
i ++;
}
console.log("test");
运行以上代码,你会发现,上面的函数会等待while循环执行完毕之后才会运行,同时你还会发现,here输出在test的后面;
用伪代码表示就是(顺序自上而下)
主线程:
for (var i = 0; i < 10; i++) {
setTimeout(function() {
}, 0);
//注册了10个定时器
}
//....执行其他的代码
//执行异步代码:
//这时i已经变成了10,i=10;
//console.log(i) 10次
异步其实就是你去吃饭,但是厨师告诉你不能立即做好,需要等一段时间(主线程在跑其他代码)。
然后因为你很饿,所以你催了10次(注册了10次异步)。
等厨师有时间了,才回应你的要求并且给你做饭。
setTimeout(function(){
console.log(1);
}, 2000);
console.log(2);
你看看 1 先输出还是 2 先输出,所谓异步,就是脱离你目前的执行流程。
这里绝对有闭包的作用,你不知道的js上册说的很清楚。
比如
for( var i=1; i<=10; ++i ){
(function(){
var j = i
setTimeout( function(){console.log(j)},0 )
})()
}
这里就会输出1,2,3。。。。10
8 回答4.8k 阅读✓ 已解决
6 回答3.5k 阅读✓ 已解决
5 回答2.9k 阅读✓ 已解决
5 回答6.4k 阅读✓ 已解决
4 回答2.3k 阅读✓ 已解决
5 回答1.3k 阅读✓ 已解决
4 回答2.8k 阅读✓ 已解决
你问为什么这里输出10的原因是异步?
我只能告诉你,因为
setTimeout()
函数是异步的为什么
setTimeout()
函数是异步的?这个问题你得去问
Brendan Eich
。如果你想问的是这里为什么输出10?
因为异步函数必须等主进程运行完毕才会运行,
setTimeout()
内部回调运行的时候,主进程已经运行完毕了,此时i=10
,所以输出10。