JS运行机制(异步和单线程)

题目1

console.log(1);
setTimeout(() => {
    console.log(2);
}, 1000);
console.log(3);

// 运行结果1 3 2

分析:
这个运行结果很正常,因为2的输出要延迟一秒,所以3会先输出。

题目2

console.log(1);
setTimeout(() => {
    console.log(2);
}, 0);
console.log(3);

// 运行结果1 3 2

困惑:
这里我们设定了2的等待时间是0秒,0秒就是不需要等待。
那输出应该是1 2 3呀,为什么实际却还是1 3 2 ?

分析:
这里就引出的js运行机制的两个概念,单线程和任务队列。
JS的运行是单线程的,所谓单线程,意思是说js在一个同一时间只能做一件事情。

所谓任务队列,就是JS的执行任务,其中包含同步任务和异步任务。
在本题中,console.log(1);console.log(3);都属于同步任务,setTimeout属于异步任务。

首先,同步任务console.log(1);会直接执行。
然后,遇到下一步的异步任务setTimeout,JS会将此任务挂起(先不执行),直接往下走。
再次,同步任务console.log(3);会直接执行。
最后,所有的同步任务都处理之后,再去响应异步任务。

所以,虽然setTimeout的时间是0,但是因为它是一个异步任务,所以是最后执行的。
导致最终的运行结果是1 3 2。

知识点:
同步任务的优先级高于异步任务

题目3

console.log(1);
while(true){

}
console.log(2);

// 运行结果1

分析:
while是一个同步任务,所以会按顺序先while,在执行console.log(2);
while没有执行完之前,console.log(2);是不会执行的。

题目4

console.log(1);
setTimeout(() => {
    console.log(2);
}, 0);
while(true){

}

// 运行结果1

分析:
setTimeout是一个异步任务,在所有通过任务没有执行完之前,是不会执行的。
所以,虽然在物理上,setTimeout写在while之前,但是2也是无法输出的。

题目5

for(var i=0;i<4;i++){
    setTimeout(() => {
        console.log(i)
    }, 1000);
}

// 运行结果(4)4

困惑:
一般理解应该是0 1 2 3才对,怎么是4个4呢?

分析:

  1. 每次执行for循环的时候,由于循环体里面是一个异步任务,所有JS不会去执行它。
  2. for循环接着往下执行,直到循环结束,这时候i的值已经是4了。这个过程非常快,大概1毫秒都不到。
  3. 同步任务(也就是4个for循环体)执行完之后,会去执行异步任务。但是这个时候异步队列中是没有任务的。所以什么也不会做。
  4. 浏览器中有个时间模块,当这个时间模块检测到时间(这里就是1秒)到了,才会把异步放入异步队列中。所以1秒之后,这些异步任务开始执行。而输出的结果都是4,因为在第2步的时候,i已经变成4了。

知识点:
异步任务的放入时间:setTimeout中的时间到了才会放入。
异步任务的执行时间:所有同步任务执行完之后才会执行。

总结1:事件循环(Event Loop)

以下这张图可以解释js的运行机制,包括事件循环(Event Loop)

微信图片_20181130100409.png
  • 执行栈执行的是同步任务
  • 异步任务的放入时间:setTimeout中的时间到了才会放入。
  • 异步任务的执行时间:所有同步任务执行完之后才会执行。
  • 开启异步任务的情况:
    定时任务:setTimeout和setInterval
    网络请求:ajax请求,动态<img>加载
    事件绑定(DOM事件)
    ES6中的Promise

总结2:同步与异步的区别

  • 同步会阻塞代码的执行
console.log(100);  // 第一步:打印100
alert(200);        // 第二步:弹框显示200,等待用户点击确定按钮(alert是同步处理)
console.log(300)   // 第三步:用户点击上一步的确认按钮之后,显示300
  • 异步不会阻塞代码的执行
console.log(100);      // 第一步:打印100
setTimeout(() => {
    console.log(200);  // 第三步:1秒之后打印200
}, 1000);
console.log(300)       // 第二步:打印300
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容