javascript - 如何理解setTimeout里面的异步?
天蓬老师
天蓬老师 2017-04-11 11:42:47
[JavaScript讨论组]

比如:

for(var i=0;i<10;i++){
    setTimeout(function() {
        console.log(i);
    }, 0);
}

我一直以为这里是因为闭包才输出10个10,后来面试官告诉我是因为异步,为什么是异步呢?

天蓬老师
天蓬老师

欢迎选择我的课程,让我们一起见证您的进步~~

全部回复(8)
天蓬老师
  1. 你问为什么这里输出10的原因是异步?
    我只能告诉你,因为setTimeout()函数是异步的

  2. 为什么setTimeout()函数是异步的?
    这个问题你得去问Brendan Eich

  3. 如果你想问的是这里为什么输出10?
    因为异步函数必须等主进程运行完毕才会运行,setTimeout()内部回调运行的时候,主进程已经运行完毕了,此时i=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的后面;

黄舟

彻底理解同步、异步和事件循环(Event Loop)

天蓬老师

用伪代码表示就是(顺序自上而下)
主线程:

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 先输出,所谓异步,就是脱离你目前的执行流程。

伊谢尔伦

因为 settimeout 就是被设计成异步的啊,难不成你是想问它为什么是异步的!

大家讲道理

哪里有闭包? 闭包是为了不输出 10 个 10 吧?

伊谢尔伦

推荐你看下这篇文章,刚好说的就是这个问题,里面讲解的很详细
80% 应聘者都不及格的 JS 面试题

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号