JS同步执行、异步执行、及同步中的异步执行

首先明确两点:

1.JS 执行机制是单线程。

2.JS的Event loop是JS的执行机制,深入了解Event loop,就等于深入了解JS引擎的执行。

单线程执行带来什么问题?

在JS执行中都是单线程执行,所以代码的执行可以说是自上而下,如果前一段的代码出现问题,就会导致下一段代码无法执行,对于用户而言就是卡死现象,所以在JS执行机制引出了异步执行操作。

那异步能解决什么呢问题,又会带来什么问题?

异步操作能够很好的解决上面单线程执行出现的卡死现象,但是也会产生问题,比如同时对一件事情操作,不知道应该先执行那件事。

那么同步中使用异步如何实现呢?

是通过的事件循环(Event loop)那先了解下Event loop吧。

先看一下,以下代码(1)

注意观察执行顺序

有点JS 基础的同学会容易就知道了运行结果。

运行结果是:1、3、2

大家都知道setTimeout里的函数并没有立即执行,而是延迟一段时间,符合特定的条件才开始执行,这就是异步执行操作。

由此执行我们先了解到JS任务的执行分类为:同步任务和异步任务。


按照这种的分类方式JS的执行机制是:

首先,判断JS是同步还是异步,同步进入主线程,异步进入Event table

其次,异步任务在Event table中注册函数,当满足特定的条件,被推入Event queue

最后,同步任务进入主线程后一直执行,直到主线程空闲后,才会去Event queue中查看是否有可执行的异步任务,如果有就推入主线程中执行。

循环以上三步执行,这就是Event loop。

所以上面的例子的执行顺序是

console.log("1")是同步任务,放入主线程,

setTimeout()是异步任务,被放入Event table,0秒后被推入Event queue里,

console.log("3")是同步任务,放入主线程

当1、3任务先执行完后,主线程去Event queue(事件队列)里查看是否有可执行的函数,执行setTimeout里的函数。

所以,上面关于Event loop就是我对JS执行机制的理解,直到遇到了下面这段代码(2)。


 那我们也按着上面总结的JS执行分类分析:

setTimeout是异步任务,被放到event table

newPromise是同步任务,被放到主进程里,直接执行打印console.log('马上执行for循环啦')

.then里的函数是 异步任务,被放到event table

console.log('代码执行结束')是同步代码,被放到主进程里,直接执行

所以最后的执行结果是:【准备执行for循环-->代码执行完毕-->定时器开始执行-->执行then函数 】,对吗?

最后执行后发现结果并非是你想的这样,而是【准备执行for循环-->代码执行完毕-->执行then函数-->定时器开始执行】,为什么会是这样呢?难道是异步任务执行的顺序不是前后顺序,而是另有规定?事实上,按照异步同步的划分并不准确。

而准确的方式应该是:

macro-task(宏任务):包括整体代码script,setTimeout,setInterval

micro-task(微任务):Promise,process.nextTic

 按照上图这种分类方式:JS 的执行机制是:

执行一个宏任务,过程中如果遇到微任务,就将其放到微任务的【事件队列】里

当前宏任务执行完成后,会查看微任务的【事件队列】,并将里面全部的微任务依次执行完

重复以上2步骤,结合event loop(1) event loop(2) ,就是更为准确的JS执行机制了。

按照这种执行机制,去分析第二段代码


首先执行script下的宏任务,遇到setTimeout,将其放到宏任务的【队列】里

遇到 new Promise直接执行,打印"准备执行for循环"

遇到then方法,是微任务,将其放到微任务的【队列里】

打印 "代码执行完毕"

本轮宏任务执行完毕,查看本轮的微任务,发现有一个then方法里的函数, 打印"执行then函数"

到此,本轮的event loop 全部完成。

下一轮的循环里,先执行一个宏任务,发现宏任务的【队列】里有一个 setTimeout里的函数,执行打印"定时器开始执行"

所以最后的执行顺序就是:【准备执行for循环-->代码执行完毕-->执行then函数-->定时器开始执行】

最后再说一下setTimeout

先看一段代码

我们一般说这段代码,在3秒后执行setTimeout内的函数。

setTimeout(function(){

    console.log('执行了')

},3000) 

但这种说法往往是不够严谨的,准确的解释是:3秒后,setTimeout函数会被推入Event queue(事件队列),而Event queue(事件队列)内的任务,只有在主线程空闲时才会执行。

所以,只有同时满足以下条件setTimeout内的函数才能被执行

1.3秒后

2.主线程空闲时

若主线程的执行任务很多,执行时间超过3秒,比如说5秒,那么setTimeout内的函数只能在5秒后执行了 

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

推荐阅读更多精彩内容