JavaScript 異步與同步
首先问畅,說一下什么是異步艾栋,什么是同步爆存。
具提詳細的定義網(wǎng)上一大堆,我這里僅僅說下我個人的理解蝗砾。
同步就是先较,只做一點事情,如果這個過程中需要等待悼粮,那么就空閑在哪里闲勺,等到得到了想要的結(jié)果再去繼續(xù)處理別的事情。舉個例子扣猫,在處理一些數(shù)據(jù)的時候菜循,需要做一個網(wǎng)絡(luò)請求,獲得處理所需的一些東西苞笨。所以债朵,要等到網(wǎng)絡(luò)返回結(jié)果后接著去處理剩下的邏輯。
等待的結(jié)果是一個漫長的過程瀑凝,萬一沒有結(jié)果呢序芦?
所以,才有了異步粤咪。異步就是一事情做到一半谚中,發(fā)現(xiàn)需要等待一段時間,這個時候我們把這個事情暫時放在一邊。去作別的事情宪塔,等到空閑的時候再去看我們做到一半的事情磁奖,有沒有具備條件可以寄繼續(xù)執(zhí)行。如果有那么就可以去執(zhí)行它某筐。
我們都知道JavaScript是一門同步執(zhí)行的語言比搭,但是我們在使用的時候卻又很多異步的操作如settimeout, ajax等南誊。這些操作是如何實現(xiàn)的呢身诺?
線程和進程
進程
- 程序運行的實例
- 同一個程序可以產(chǎn)生多個進程
- 一個進程可以包含一個或者多個線程
線程
- 操作系統(tǒng)中能都進行運算調(diào)度的最小單位
- 一次只能執(zhí)行一個任務(wù)
- 有自己的調(diào)用棧,寄存器環(huán)境
- 同一個進程下的線程共享進程的資源
瀏覽器的進程
WX20200320-224418@2x.png
- GUI線程 解析html抄囚,解析css霉赡,構(gòu)建dom樹等
- js引擎線程,解析并執(zhí)行js幔托,與GUI線程互斥穴亏。長時間同步執(zhí)行js會導(dǎo)致GUI線性停頓,從而感覺瀏覽器卡主了重挑。
- 定時器觸發(fā)線程:settimeout setinterval
- 事件觸發(fā)線程:將滿足調(diào)試的事件嗓化,放入任務(wù)隊列
- 網(wǎng)絡(luò)線程:用于處理一些網(wǎng)絡(luò)請求
定時器
代碼
settimeout(() => {
console.log('我執(zhí)行了')
}, 2000)
上面就是我們使用定時器的一個簡單示例,具體執(zhí)行順序入下攒驰。
- 調(diào)用webapi蟆湖, 這個主要是要請求一個計時器故爵,
- 定時器即使2s玻粪,
- 事件觸發(fā)線程將時間翻入任務(wù)對了中
- 主線程通過eventLoop執(zhí)行
eventLoop是一個任務(wù)隊列,如果eventLoop中有元素诬垂,主線程會不斷的輪詢eventLoop中是否有元素劲室,如果就將其取出并執(zhí)行
定時器的弱點
- 定時器并不是嚴格準時的
- 定時器嵌套5次之后最小間隔不能低于4ms,不同的瀏覽器中有不同的實現(xiàn)结窘。
定時器的使用場景
- 防抖 節(jié)流
- 倒計時
- 定時器動畫很洋,有可能出現(xiàn)丟幀
參考文章
https://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html
https://juejin.im/post/5bd7c761518825292d6b0217