Js的同步異步以及回調(diào)函數(shù)

1.背景介紹

什么是同步愤炸,什么是異步?
  • 同步指的是一次只能完成一件任務(wù)。如果有多個任務(wù)矾睦,就必須排隊晦款,前面一個任務(wù)完成,再執(zhí)行后面一個任務(wù)枚冗,以此類推缓溅。
  • 異步指的是每一個任務(wù)有一個或多個回調(diào)函數(shù)(callback),前一個任務(wù)結(jié)束后赁温,不是執(zhí)行后一個任務(wù)坛怪,而是執(zhí)行回調(diào)函數(shù),后一個任務(wù)則是不等前一個任務(wù)結(jié)束就執(zhí)行股囊,所以程序的執(zhí)行順序與任務(wù)的排列順序是不一致的袜匿、異步的。

2.知識剖析

javascript實現(xiàn)異步的原理

首先js是單線程的語言稚疹,即同一時間只能做做一件事居灯。那Js如何實現(xiàn)異步的,異步和單線程不是自相矛盾嗎内狗?其實怪嫌,單線程和異步確實不能同時成為一個語言的特性。js選擇了成為單線程的語言柳沙,所以它本身不可能是異步的岩灭,但js的宿主環(huán)境(比如瀏覽器,Node)是多線程的赂鲤,宿主環(huán)境通過某種方式(事件驅(qū)動噪径,下文會講)使得js具備了異步的屬性

瀏覽器的內(nèi)核是多線程的,它們在內(nèi)核制控下相互配合以保持同步蛤袒,一個瀏覽器至少實現(xiàn)三個常駐線程:javascript引擎線程熄云,UI渲染線程琼梆,瀏覽器事件觸發(fā)線程兔仰。
  1. javascript引擎線程是基于事件驅(qū)動單線程執(zhí)行的,JS引擎一直等待著任務(wù)隊列中任務(wù)的到來杯巨,然后加以處理珍德,瀏覽器無論什么時候都只有一個JS線程在運行JS程序练般。

  2. UI渲染線程負(fù)責(zé)渲染瀏覽器界面,當(dāng)界面需要重繪(Repaint)或由于某種操作引發(fā)回流(reflow)時,該線程就會執(zhí)行锈候。但需要注意UI渲染線程與JS引擎是互斥的薄料,當(dāng)JS引擎執(zhí)行時UI線程會被掛起,UI更新會被保存在一個隊列中等到JS引擎空閑時立即被執(zhí)行.

  3. 事件觸發(fā)線程泵琳,當(dāng)一個事件被觸發(fā)時該線程會把事件添加到待處理隊列的隊尾摄职,等待JS引擎的處理誊役。這些事件可來自JavaScript引擎當(dāng)前執(zhí)行的代碼塊如setTimeOut、也可來自瀏覽器內(nèi)核的其他線程如鼠標(biāo)點擊谷市、AJAX異步請求等蛔垢,但由于JS的單線程關(guān)系所有這些事件都得排隊等待JS引擎處理。


    image

UI線程和JS線程互斥的實例

<input type="text" value="" name="input" onkeydown="console.log(this.value)">
<input type="text" value="" name="input" onkeydown="var me=this;setTimeout(function(){console.log(me.value)},0)">

分析:第一個在keydown的時候迫悠,彈出來的是input里原來的value鹏漆,而第2個在keydown的時候,卻能彈出更新后的value创泄,就是因為setTimeout艺玲,雖然他的delay設(shè)置為0,幾乎是即時觸發(fā)鞠抑,但還是被添加到了執(zhí)行隊列后面饭聚,但就是這個過程,渲染已經(jīng)完成了碍拆,當(dāng)他回調(diào)函數(shù)執(zhí)行時若治,輸出來的已經(jīng)是更新后的value了。

注意:js的工作機制是當(dāng)線程空閑的情況下才會執(zhí)行異步代碼的回調(diào)函數(shù)
即當(dāng)所有同步任務(wù)執(zhí)行完畢后才會執(zhí)行異步任務(wù)的回調(diào)函數(shù)

總結(jié):當(dāng)Js執(zhí)行到異步任務(wù)后感混,會將異步任務(wù)交給瀏覽器進行執(zhí)行端幼,當(dāng)執(zhí)行有結(jié)果時會把異步任務(wù)的回調(diào)函數(shù)插入待處理隊列的隊尾。


3.常見問題

  1. ajax發(fā)送異步請求瀏覽器做了什么
  2. 有哪些常見異步回調(diào)函數(shù)弧满?

4.解決方案

  1. ajax發(fā)送異步請求瀏覽器做了什么婆跑?
  • Js創(chuàng)建了一個ajax請求
  • 瀏覽器另外開啟一個ajax引擎線程,執(zhí)行ajax請求
  • 執(zhí)行得到響應(yīng)后將回調(diào)函數(shù)放入任務(wù)隊列中庭呜。
  • Js執(zhí)行任務(wù)隊列中的回調(diào)函數(shù)滑进。
  1. 有哪些常見的異步回調(diào)函數(shù)?
  • 點擊事件
  • Ajax請求
  • 定時器
  1. 瀏覽器處理點擊事件的過程
  • 瀏覽器開啟事件觸發(fā)線程募谎,等待用戶動作扶关,事件觸發(fā)線程解析為響應(yīng)事件,轉(zhuǎn)移到j(luò)avascript引擎線程数冬,排隊等候节槐,等待javascript引擎的處理。
    例:
<!doctype html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
<div onclick="clickme()">click me</div>
<script type="text/javascript">
    function clickme() {
        console.log('點擊事件')
    }
    for (i=0;i<50000;i++){
        console.log(i)
    }
</script>
</body>
</html>

在線實例
這個點擊事件會等到for循環(huán)執(zhí)行完畢后才會執(zhí)行拐纱,即我們點擊模塊它直到for循環(huán)執(zhí)行完畢才會執(zhí)行


5.編碼實戰(zhàn)


6.擴展思考

如何實現(xiàn)js的多線程操作铜异?
  • Html5的web worker

7.更多討論

  • Q1:瀏覽器的UI線程和Js線程為什么是互斥的?
  • A1:而因為JS可以操作DOM元素秸架,進而會影響到GUI的渲染結(jié)果揍庄,因此JS引擎線程與GUI渲染線程是互斥的。
  • Q2:異步函數(shù)有哪些優(yōu)點和缺點
  • A2:
    優(yōu)點:
    a)對CPU的使用率高东抹。
    b)不用考慮線程間同步互斥問題蚂子。
    缺點:
    a)實現(xiàn)較復(fù)雜沃测,要把所有會導(dǎo)致阻塞的操作轉(zhuǎn)化為異步操作。
    b)并發(fā)性不好缆镣,在有的事件需要長時間占用CPU處理的情況下芽突,其他事件會長時間等待得不到處理。
    c)在多CPU時不如多線程高效董瞻。
  • Q3:異步函數(shù)跟promise之間有什么關(guān)系?
    A3:Promise它可以用于異步的回調(diào)函數(shù)田巴,它跟傳統(tǒng)的回調(diào)函數(shù)相比钠糊,promise的異步回調(diào)函數(shù)代碼書寫起來更優(yōu)雅,更便于閱讀壹哺。

8.參考文獻

參考一:js的單線程和異步
參考二:深入理解javascript異步編程障眼法&&h5 web worker實現(xiàn)多線程
參考三:談?wù)凧avaScript的異步實現(xiàn)- 小方- 博客園


PPT
視頻

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末抄伍,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子管宵,更是在濱河造成了極大的恐慌截珍,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,430評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件箩朴,死亡現(xiàn)場離奇詭異岗喉,居然都是意外死亡,警方通過查閱死者的電腦和手機炸庞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評論 3 398
  • 文/潘曉璐 我一進店門钱床,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人埠居,你說我怎么就攤上這事查牌。” “怎么了滥壕?”我有些...
    開封第一講書人閱讀 167,834評論 0 360
  • 文/不壞的土叔 我叫張陵纸颜,是天一觀的道長。 經(jīng)常有香客問我绎橘,道長胁孙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,543評論 1 296
  • 正文 為了忘掉前任金踪,我火速辦了婚禮浊洞,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘胡岔。我一直安慰自己法希,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,547評論 6 397
  • 文/花漫 我一把揭開白布靶瘸。 她就那樣靜靜地躺著苫亦,像睡著了一般毛肋。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上屋剑,一...
    開封第一講書人閱讀 52,196評論 1 308
  • 那天润匙,我揣著相機與錄音,去河邊找鬼唉匾。 笑死孕讳,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的巍膘。 我是一名探鬼主播厂财,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼峡懈!你這毒婦竟也來了璃饱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,671評論 0 276
  • 序言:老撾萬榮一對情侶失蹤肪康,失蹤者是張志新(化名)和其女友劉穎荚恶,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體磷支,經(jīng)...
    沈念sama閱讀 46,221評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡谒撼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,303評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了齐唆。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嗤栓。...
    茶點故事閱讀 40,444評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖箍邮,靈堂內(nèi)的尸體忽然破棺而出茉帅,到底是詐尸還是另有隱情,我是刑警寧澤锭弊,帶...
    沈念sama閱讀 36,134評論 5 350
  • 正文 年R本政府宣布堪澎,位于F島的核電站,受9級特大地震影響味滞,放射性物質(zhì)發(fā)生泄漏樱蛤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,810評論 3 333
  • 文/蒙蒙 一剑鞍、第九天 我趴在偏房一處隱蔽的房頂上張望昨凡。 院中可真熱鬧,春花似錦蚁署、人聲如沸便脊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽哪痰。三九已至遂赠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間晌杰,已是汗流浹背跷睦。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留肋演,地道東北人抑诸。 一個月前我還...
    沈念sama閱讀 48,837評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像惋啃,于是被迫代替她去往敵國和親哼鬓。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,455評論 2 359