日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

單線程JavaScript實現異步過程詳解

瀏覽:28日期:2023-10-26 11:32:30

前兩天硬著頭皮在部門內部做了一次技術分享,主題如題。索性整理成文章留個紀念!

要了解異步實現,首先我們得先了解:

同步 & 異步

同步:會逐行執行代碼,會對后續代碼造成阻塞,直至代碼接收到預期的結果之后,才會繼續向下執行任務。

異步:調用之后先不管結果,繼續向下執行任務。

網上各種文章對同步和異步的解釋也不外如是,但是看文字總是有點晦澀難懂!我就生活化的來比擬一下這兩個概念吧!

就好比請人吃飯:

比如你要請兩個人吃飯,一個是巴菲特,由于他是舉世矚目股神想請他吃飯的人從這里排到了法國,你為表誠意,你會精心打扮自己,然后租一架飛機親自去美國,請他跟你吃頓特色菜...那么為了請他吃個烤腰子,你全程都在為些事費心費力,投入大量的精力!

所以,也就阻塞了你干別的事情,是的,這就是同步!

請人吃頓飯就這么難嗎?當然,也沒有那么難!不信,你請我吃飯試試:

如果你想請我吃飯,那你只需要打個電話通知我一聲:喂,今天晚上請你吃個海底撈啊!我:好啊!然后你不要來接我,到了點我自己去了!期間,你該干嘛就去干嘛!

看,其他也很簡單嘛?瞧,這就是異步!

那么回到代碼層面:

同步代碼:(代碼片段1)

function someTime() { let s = Date.now(); while(true) { if (Date.now() - s > 2000) { console.log(2) break; } }}console.log(1);someTime();console.log(3);// 其打印順序:1 ...(2秒以后)... 2 3

異步代碼:(代碼片段2)

function someTime() { setTimeout(() => { console.log(2); }, 2000)}console.log(1);someTime();console.log(3);// 其打印順序:1 3 ...(2秒以后)... 2

看看,同步代碼,當執行這種耗時操作時,就會停在原地,一定要等待這時間過去之后才會執行后面的代碼!而異步代碼,后面的執行完全不受影響...

JavaScript單線程

眾所周知JavaScript是單線程的,所謂單線程是指程序執行時,所走的程序路徑按照連續順序排下來,前面的必須處理好,后面的才會執行!這個解釋跟【同步】的解釋如出一轍!

如此看起來異步編程對于單線程而言似乎并非正統,甚至有點矛盾。然而,通過剛才的例子,我們發現,JavaScript是真的實現了異步編程的!為啥加了個setTimeout()不能不阻塞了呢?按單線程的執行的話那如下代碼會是怎么樣的呢?

function timeOut() { setTimeout(() => { console.log(’timeOut’); }, 0)}function someTime() { let s = Date.now(); while(true) { if (Date.now() - s > 2000) { console.log(’some Time’) break; } }}console.log(1);timeOut();someTime();console.log(3);

如果是以單線程那種解釋來執行的話,這個打印順序應該是:1 - time Out - some Time - 3才對!然而,其真正的執行結果卻是:1 - some Time - 3 - time Out

為什么?瀏覽器的多線程

JavaScript是腳本語言,它需要在一個宿主環境里才能運行,顯然我們接觸較多的宿主環境就是--瀏覽器!雖說JavaScript是單線程的,然而瀏覽器卻不是!

單線程JavaScript實現異步過程詳解

如圖所求,JavaScript引擎線程稱為主線程,它負責解析JavaScript代碼;其他可以稱為輔助線程,這些輔助線程便是JavaScript實現異步的關鍵了!

如(代碼片段2):主線程負責自上而下順序執行,當遇到setTimeout函數后,便將其交給定時器線程去執行,自己繼續執行下面的代碼!從而達到異步的目的。

不僅如此,更關鍵的是:

單線程JavaScript實現異步過程詳解

任務隊列

當定時器線程計時執行完之后,會將回調函數放入任務隊列中!

當這些任務加入到任務隊列后并不會立即執行,而是處于等候狀態!等主線程處理完了自己的事情后,才來執行任務隊列中任務!

這個過程我感覺像是古代嬪妃被翻了牌子后,就需要在自己寢宮里精心準備,等待皇上批完湊折后的駕臨...(哦,別想歪了!)

宏任務 & 微任務

然而,異步任務卻又分為兩種:一種叫“宏任務”(MacroTask 或者 Task),一種叫“微任務”(MicroTask)!

這又是兩個啥玩意呢?

單線程JavaScript實現異步過程詳解

光看這個依然晦澀難懂,那我們來看一段代碼吧!

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

這段代碼的執行結果:1 - 4 - 3 - 2。LOOK!2是最后打印的,哪怕該計時器的時間設置為0。通過之前的同步和異步的解釋,1和4先于2打印應該很好理解了,但同樣是異步,3也優先于2打印,這又是為什么呢?答案就是因為 setTimeout屬于宏任務,而Promise屬于微任務!

好吧~ 這就是宏任務和微任務的差別...什么?沒懂?

微任務是皇后所生的,是嫡子;而宏任務是某個小妃子所生, 是庶子!你說選太子的時候誰優先?

瀏覽器的Event Loop

1.執行全局Script同步代碼,形成一個執行棧;

2.在執行代碼時當遇到如上異步任務時便會按上文所描述的將宏任務回調加入宏任務隊列,微任務回調加入微任務隊列;

3.然而,回調函數放入任務隊列后也不是立即執行;會等待執行棧中的同步任務全部執行完清空了棧后引擎才能會去任務隊列檢查是否有任務,如果有那便會將這些任務加入執行棧,然后執行!

4.執行棧清空后,會先去檢查微任務隊列是否有任務,逐一將其任務加入執行棧中執行,期間如果又產生了微任務那繼續將其加入到列隊末尾,并在本周期內執行完,直到微任務隊列的任務全部 清空,執行棧也清空后,再去檢查宏任務隊列是否有任務,取到隊列隊頭的任務放入到執行棧中執行,其他可能又會產生微任務,那當本次執行棧中的任務結果清空后又會去檢查微任務隊列...

5.引擎會循環執行如上步驟,這就是Event Loop!

單線程JavaScript實現異步過程詳解

又要上代碼了:

console.log(’start’);setTimeout(() => { console.log(’time1’); Pormise.resolve().then(() => { console.log(’promise1’); })}, 0);setTimeout(() => { console.log(’time2’); Pormise.resolve().then(() => { console.log(’promise2’); })}, 0);Pormise.resolve().then(() => { console.log(’promise3’);});console.log(’end’);

這段代碼的打印順序:

start - end - promise3 - timer1 - promise1 - timer2 - promise2

據說:node 10.x版本上面的輸入結果會是:

start - end - promise3 - timer1 - timer2 - promise1 - promise2

node 11.x版本以后改了,輸出跟瀏覽器輸出一致了!

Web Worker

HTML5中支持了Web Worker,使得能夠同時執行兩段JS了,那是不是就是說JS實現了“多線程”了呢?我們來看看Web Worker的官方解釋:

通過使用Web Workers,Web應用程序可以在獨立于主線程的后臺線程中,運行一個腳本操作。這樣做的好處是可以在獨立線程中執行費時的處理任務,從而允許主線程(通常是UI線程)不會因此被阻塞/放慢。

獨立線程,看似像是實現了“多線程”,然而他是獨立于主線程,也就是主線程依然是那個主線程沒有變!雖然你大媽已經不是你大媽了,但是你大爺還是你大爺!JS單線程的本質依然沒有變!

WebWorker是向瀏覽器申請一個子線程,該子線程服務于主線程,完全受主線程控制。

Web Worker注意事項:

單線程JavaScript實現異步過程詳解

寫了一個demo:

<!DOCTYPE html><html lang='en'><head> <meta charset='UTF-8'> <meta name='viewport' content='width=device-width, initial-scale=1.0'> <title>Web Worker</title></head><body> <button onclick='startWorker()'>開始</button> <button onclick='stopWorker()'>停止</button> <button onclick='updateNum()'>在運行時點擊</button> <div id='output'></div> <div id='num'></div> <script type='app/worker'> function updateSync() { for (let i = 0; i < 10000000000; i++) {if (i % 100000 === 0) { postMessage(i);} } } updateSync(); </script> <script> let worker; function startWorker() { let blob = new Blob([document.querySelector(’#worker’).textContent]); let url = window.URL.createObjectURL(blob); console.log(url); worker = new Worker(url); worker.onmessage = function(e) {document.getElementById(’output’).innerHTML = e.data; } } function stopWorker() { if (worker) {worker.terminate(); } }let num = 0; function updateNum() { num++; document.getElementById(’num’).innerHTML = num; } </script></body></html>

這段代碼可以稍微解釋一下Web Worker的用途之一 --執行費時的處理任務吧!

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網。

標簽: JavaScript
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日韩专区欧美专区| 日韩高清欧美激情| 欧美精品1区| 国产日韩亚洲| 欧美日韩亚洲一区三区| 91精品尤物| 国产精品一区二区精品视频观看 | 精品一区三区| 久久久久久黄| 欧美日韩在线播放视频| 99久久精品费精品国产| 日韩欧美精品| 久久久久国产精品一区二区| 久久影院一区| 亚洲自啪免费| 一区二区精彩视频| 日韩激情中文字幕| 久久激情av| 精品一区二区三区中文字幕 | sm久久捆绑调教精品一区| 捆绑调教日本一区二区三区| 伊人久久高清| 欧美精品一卡| 亚洲69av| 国产精品115| 国产91在线播放精品| 日韩国产综合| 伊人久久亚洲热| 日韩欧美三区| 精品日本视频| 久久精品国产99久久| 美国三级日本三级久久99| 日韩av成人高清| 久久精品国产99| 久久久影院免费| 最新亚洲国产| 精品视频在线你懂得| 日韩精品网站| 亚洲伊人影院| 嫩草伊人久久精品少妇av杨幂| 在线观看精品| 日韩制服丝袜av| 国产精品美女午夜爽爽| 日韩福利一区| 久久国产精品久久久久久电车 | 亚洲深夜福利在线观看| 国产日本久久| 日韩高清中文字幕一区二区| 亚洲欧美日韩视频二区| 国产精品久久乐| 亚洲国产影院| 日本va欧美va精品发布| 日韩久久一区二区三区| 亚洲精品九九| 中文在线а√天堂| 亚洲影视一区二区三区| 日产午夜精品一线二线三线| 国产精品嫩草99av在线| 国产欧美一级| 久久高清免费| 国产欧美日韩精品高清二区综合区| 精品国产99| 爽好多水快深点欧美视频| 精品欧美日韩精品| 日韩精品一二三区| 美女av在线免费看| 日本在线视频一区二区| 欧美va亚洲va日韩∨a综合色| 91精品国产自产在线丝袜啪| 日韩精品网站| 欧美一区成人| 亚洲性视频h| 蜜桃精品视频| 日韩精品一级中文字幕精品视频免费观看 | 中国字幕a在线看韩国电影| 四虎精品永久免费| 久久三级视频| 国产日韩一区| 欧美综合国产| 国产精品原创| 青青草国产成人99久久| 不卡一区2区| 精品视频一区二区三区在线观看 | 视频一区视频二区在线观看| 深夜福利视频一区二区| 91亚洲无吗| 国产免费成人| 精品日韩视频| 里番精品3d一二三区| 日韩在线一区二区| 国产精品99免费看| 国产精品久久久久蜜臀| 欧美日本不卡| 国产精品普通话对白| 久久久精品久久久久久96| 麻豆精品久久| 国产视频一区二| 亚洲欧美日本国产| 国产亚洲在线观看| 在线看片国产福利你懂的| 国产精品a级| 日本免费一区二区视频| 蜜桃免费网站一区二区三区| 欧美成a人国产精品高清乱码在线观看片在线观看久 | 噜噜噜躁狠狠躁狠狠精品视频 | 中文字幕视频精品一区二区三区| 日韩理论视频| 精品亚洲a∨一区二区三区18| 欧美性www| 亚洲精品亚洲人成在线观看| 国产一区白浆| 悠悠资源网久久精品| 亚洲一级二级| 亚洲视频综合| 久久美女精品| 在线国产一区二区| 久久久9色精品国产一区二区三区| 日韩1区在线| 综合日韩av| 国产网站在线| 神马久久午夜| 成人av三级| 日韩在线不卡| 不卡一二三区| 久久久久久久久久久妇女 | 亚洲久久视频| 亚洲另类视频| 亚欧洲精品视频在线观看| 日韩欧美久久| 国产午夜久久av| 老鸭窝一区二区久久精品| 国产精品伦理久久久久久| 成人自拍av| 久久亚洲在线| 婷婷综合激情| 欧美日韩国产综合网| 视频在线在亚洲| 日本一不卡视频| 国产欧美69| 美女视频黄久久| 一区二区精品伦理...| 国产亚洲一区二区手机在线观看| 日韩不卡免费高清视频| 婷婷色综合网| 亚洲男人在线| 国产精品亲子伦av一区二区三区| 麻豆一区在线| 日韩伦理在线一区| 久久久水蜜桃av免费网站| 午夜免费一区| 亚洲综合小说| 国产欧美69| 丝袜诱惑一区二区| 欧美在线亚洲综合一区| 一区二区国产在线观看| 欧美性www| 黄色在线网站噜噜噜| 99综合视频| 日韩欧美精品一区二区综合视频| 久久免费精品| 国产一区亚洲| 日本亚洲欧洲无免费码在线| 国产精品夜夜夜| 在线人成日本视频| 亚洲在线免费| 国产精品久久久久久妇女| 日韩在线欧美| 亚洲欧美日本日韩| 欧美日韩亚洲一区二区三区在线| 成人国产精品久久| 91久久久久| 国产女人18毛片水真多18精品| 日韩欧美看国产| 一区二区三区网站| 精品久久97| 美女精品在线观看| 国产极品久久久久久久久波多结野| 精品国产免费人成网站| 香蕉视频成人在线观看| 国产乱码精品一区二区三区亚洲人 | 高潮久久久久久久久久久久久久| 久久精品国产亚洲夜色av网站| 亚洲精品免费观看| 色综合狠狠操| 香蕉久久国产| 福利欧美精品在线| 欧美在线综合| 狠狠久久伊人| 蜜臀精品久久久久久蜜臀| 欧美激情麻豆| 激情欧美国产欧美| 国产精品99精品一区二区三区∴ | 亚洲精品免费观看| 国产不卡人人| 亚洲乱码视频| 久久久久久久久久久9不雅视频| 欧美久久香蕉| 欧美影院三区| 麻豆免费精品视频| 丝袜美腿亚洲一区二区图片|