大家好哟楷,我是IT修真院成都分院第10期學(xué)員李勁宏,一枚正直純潔善良的web程序員否灾,今天給大家分享JS異步與同步以及回調(diào)函數(shù)卖擅。
什么是同步,什么是異步?
同步指的是一次只能完成一件任務(wù)。如果有多個(gè)任務(wù)惩阶,就必須排隊(duì)挎狸,前面一個(gè)任務(wù)完成,再執(zhí)行后面一個(gè)任務(wù)断楷,以此類推锨匆。
異步指的是每一個(gè)任務(wù)有一個(gè)或多個(gè)回調(diào)函數(shù)(callback),前一個(gè)任務(wù)結(jié)束后冬筒,不是執(zhí)行后一個(gè)任務(wù)恐锣,而是執(zhí)行回調(diào)函數(shù),后一個(gè)任務(wù)則是不等前一個(gè)任務(wù)結(jié)束就執(zhí)行舞痰,所以程序的執(zhí)行順序與任務(wù)的排列順序是不一致的土榴、異步的。
javascript實(shí)現(xiàn)異步的原理响牛?
首先js是單線程的語言玷禽,即同一時(shí)間只能做做一件事。那Js如何實(shí)現(xiàn)異步的呀打,異步和單線程不是自相矛盾嗎矢赁?其實(shí),單線程和異步確實(shí)不能同時(shí)成為一個(gè)語言的特性贬丛。js選擇了成為單線程的語言坯台,所以它本身不可能是異步的,但js的宿主環(huán)境(比如瀏覽器瘫寝,Node)是多線程的蜒蕾,宿主環(huán)境通過某種方式(事件驅(qū)動(dòng),下文會(huì)講)使得js具備了異步的屬性
瀏覽器的內(nèi)核是多線程的焕阿,它們?cè)趦?nèi)核制控下相互配合以保持同步咪啡,一個(gè)瀏覽器至少實(shí)現(xiàn)三個(gè)常駐線程:javascript引擎線程,UI渲染線程暮屡,瀏覽器事件觸發(fā)線程撤摸。
1.javascript引擎線程是基于事件驅(qū)動(dòng)單線程執(zhí)行的,JS引擎一直等待著任務(wù)隊(duì)列中任務(wù)的到來褒纲,然后加以處理准夷,瀏覽器無論什么時(shí)候都只有一個(gè)JS線程在運(yùn)行JS程序。
2.UI渲染線程負(fù)責(zé)渲染瀏覽器界面莺掠,當(dāng)界面需要重繪(Repaint)或由于某種操作引發(fā)回流(reflow)時(shí),該線程就會(huì)執(zhí)行衫嵌。但需要注意 UI渲染線程與JS引擎是互斥的,當(dāng)JS引擎執(zhí)行時(shí)UI線程會(huì)被掛起彻秆,UI更新會(huì)被保存在一個(gè)隊(duì)列中等到JS引擎空閑時(shí)立即被執(zhí)行楔绞。
3.事件觸發(fā)線程结闸,當(dāng)一個(gè)事件被觸發(fā)時(shí)該線程會(huì)把事件添加到待處理隊(duì)列的隊(duì)尾,等待JS引擎的處理酒朵。這些事件可來自JavaScript引擎當(dāng)前執(zhí)行的代碼塊如setTimeOut桦锄、也可來自瀏覽器內(nèi)核的其他線程如鼠標(biāo)點(diǎn)擊、AJAX異步請(qǐng)求等蔫耽,但由于JS的單線程關(guān)系所有這些事件都得排隊(duì)等待JS引擎處理结耀。
注意:js的工作機(jī)制是當(dāng)線程空閑的情況下才會(huì)執(zhí)行異步代碼的回調(diào)
即當(dāng)所有同步任務(wù)執(zhí)行完畢后才會(huì)執(zhí)行異步任務(wù)的回調(diào)
異步回調(diào)函數(shù)會(huì)在執(zhí)行完所有同步任務(wù)后再執(zhí)行
總結(jié):當(dāng)Js執(zhí)行到異步任務(wù)后,會(huì)將異步任務(wù)交給瀏覽器進(jìn)行執(zhí)行匙铡,當(dāng)執(zhí)行有結(jié)果時(shí)會(huì)把異步任務(wù)的回調(diào)函數(shù)插入待處理隊(duì)列的隊(duì)尾饼记。
小課堂提問:
1.ajax發(fā)送異步請(qǐng)求瀏覽器做了什么?
1.Js創(chuàng)建了一個(gè)ajax請(qǐng)求
2.瀏覽器另外開啟一個(gè)ajax引擎線程慰枕,執(zhí)行ajax請(qǐng)求
3.執(zhí)行得到響應(yīng)后將回調(diào)函數(shù)放入任務(wù)隊(duì)列中具则。
4.Js執(zhí)行任務(wù)隊(duì)列中的回調(diào)函數(shù)。
2.有哪些常見的異步回調(diào)函數(shù)具帮?
1.點(diǎn)擊事件中作為參數(shù)的函數(shù)博肋。
2.Ajax請(qǐng)求中的then函數(shù)。
3.定時(shí)器中作為參數(shù)的函數(shù)蜂厅。
3 .同時(shí)發(fā)送兩個(gè)或以上ajax請(qǐng)求匪凡,這兩個(gè)ajax請(qǐng)求需要排隊(duì)嗎,js線程先執(zhí)行哪個(gè)ajax的回調(diào)掘猿?
同時(shí)發(fā)送多個(gè)ajax請(qǐng)求病游,瀏覽器會(huì)就會(huì)開多個(gè)ajax請(qǐng)求的線程,ajax的回調(diào)順序是稠通,哪個(gè)先請(qǐng)求成功就先執(zhí)行哪個(gè)的回調(diào)衬衬。