摘要:回調(diào)大多出現(xiàn)在請(qǐng)求,用于處理收到的請(qǐng)求結(jié)果?;卣{(diào)函數(shù)和異步一開(kāi)始我被回調(diào)和異步有點(diǎn)搞暈了。異步編程的實(shí)現(xiàn)就我目前知道兩種回調(diào)函數(shù)和事件監(jiān)聽(tīng),其實(shí)看了阮神的異步編程的文章和下面的評(píng)論之后得出的理解。為了不影響的執(zhí)行,我們可以把寫(xiě)成的回調(diào)函數(shù)。
前言
一個(gè)剛?cè)肭岸说男〔?,雖然以前看到過(guò)關(guān)于回調(diào)的文章,但是呢,理解起來(lái)有點(diǎn)費(fèi)勁啊。當(dāng)時(shí)的腦海里就一個(gè)概念。
回調(diào):大多出現(xiàn)在Ajax請(qǐng)求,用于處理收到的請(qǐng)求結(jié)果。
嘿嘿,當(dāng)時(shí)真的就是這一個(gè)想法啊?,F(xiàn)在真的入這行,而且這個(gè)概念也非常重要,用的地方太多太多,是時(shí)候把它撿起來(lái)好好理解一番。
當(dāng)然,本文適合菜鳥(niǎo),因?yàn)槲沂且砸粋€(gè)菜鳥(niǎo)的思維去理解的。
回調(diào)概念理解一個(gè)新東西,很有必須去理解下它的概念,因?yàn)檫@是最簡(jiǎn)潔明了,前人總結(jié)的。
A callback is a function that is passed as an argument to another function and is executed after its parent function has completed.
中文意思:回調(diào)是一個(gè)函數(shù)被作為一個(gè)參數(shù)傳遞到另一個(gè)函數(shù)里,在那個(gè)函數(shù)執(zhí)行完后再執(zhí)行。
有點(diǎn)繞,好,咱們說(shuō)大白話。就是 B函數(shù)被作為參數(shù)傳遞到A函數(shù)里,在A函數(shù)執(zhí)行完后再執(zhí)行B。
下面咱們看看代碼怎么實(shí)現(xiàn)回調(diào)。
function A(callback){ console.log("I am A"); callback(); //調(diào)用該函數(shù) } function B(){ console.log("I am B"); } A(B);
這應(yīng)該是最最簡(jiǎn)單的回調(diào)了,我想大家應(yīng)該明白回調(diào)的釋義了吧。
當(dāng)然,這么簡(jiǎn)單的同步回調(diào)代碼是不會(huì)用的,現(xiàn)實(shí)中用都是相對(duì)比較復(fù)雜帶傳參。
一開(kāi)始我被回調(diào)和異步有點(diǎn)搞暈了。還以為回調(diào)就一定是異步的呢。
其實(shí)不然,相信上面的A,B函數(shù)的例子我們已經(jīng)明白,回調(diào)并不一定就是異步。他們自己并沒(méi)有直接關(guān)系。
下面我們可以理解下 同步回調(diào)和異步回調(diào)(同步異步我就不多帶帶講了,概念很簡(jiǎn)單)。
同步回調(diào)就是上面的A B函數(shù)例子,它們就是同步的回調(diào)。
異步回調(diào)因?yàn)閖s是單線程的,但是有很多情況的執(zhí)行步驟(ajax請(qǐng)求遠(yuǎn)程數(shù)據(jù),IO等)是非常耗時(shí)的,如果一直單線程的堵塞下去會(huì)導(dǎo)致程序的等待時(shí)間過(guò)長(zhǎng)頁(yè)面失去響應(yīng),影響用戶體驗(yàn)了。
如何去解決這個(gè)問(wèn)題呢,我們可以這么想。耗時(shí)的我們都扔給異步去做,做好了再通知下我們做完了,我們拿到數(shù)據(jù)繼續(xù)往下走。
var xhr = new XMLHttpRequest(); xhr.open("POST", url, true); //第三個(gè)參數(shù)決定是否采用異步的方式 xhr.send(data); xhr.onreadystatechange = function(){ if(xhr.readystate === 4 && xhr.status === 200){ ///xxxx } }
上面是一個(gè)代碼,瀏覽器在發(fā)起一個(gè)ajax請(qǐng)求,會(huì)單開(kāi)一個(gè)線程去發(fā)起http請(qǐng)求,這樣的話就能把這個(gè)耗時(shí)的過(guò)程多帶帶去自己跑了,在這個(gè)線程的請(qǐng)求過(guò)程中,readystate 的值會(huì)有個(gè)變化的過(guò)程,每一次變化就觸發(fā)一次onreadystatechange 函數(shù),進(jìn)行判斷是否正確拿到返回結(jié)果。
異步編程的實(shí)現(xiàn)就我目前知道兩種 回調(diào)函數(shù) 和 事件監(jiān)聽(tīng) ,其實(shí)看了阮神的 異步編程的文章 和下面的評(píng)論之后得出的理解。下面咱們就看看這兩種異步編程的方式吧。
回調(diào)函數(shù)假定有三個(gè)函數(shù)
f1() f2() f3()
但是,f1執(zhí)行很耗時(shí),而 f2需要在f1執(zhí)行完之后執(zhí)行。
為了不影響 f3的執(zhí)行,我們可以把f2寫(xiě)成f1的回調(diào)函數(shù)。
//最原始的寫(xiě)法-同步寫(xiě)法 f1(); //耗時(shí)很長(zhǎng),嚴(yán)重堵塞 f2(); f3(); //導(dǎo)致f3執(zhí)行受到影響 //改進(jìn)版-異步寫(xiě)法 function f1(callback){ setTimeout(function () { // f1的任務(wù)代碼 callback(); }, 1000); } f1(f2); // f3();
上面的寫(xiě)法是利用 setTimeOut把f1的邏輯包括起來(lái),實(shí)現(xiàn)javascript中的異步編程。這樣的話,f1異步了,不再堵塞f3的執(zhí)行。
順道說(shuō)下,js是單線程的,這里所謂的異步也是偽異步,并不是開(kāi)了多線程的異步。它是什么原理呢,其實(shí)是任務(wù)棧,setTimeOut方法的原理是根據(jù)后面的定時(shí)時(shí)間,過(guò)了這個(gè)定時(shí)時(shí)間后,將f1加入任務(wù)棧,注意僅僅是加入任務(wù)棧,并不是放進(jìn)去就執(zhí)行,而是根據(jù)任務(wù)棧里的任務(wù)數(shù)量來(lái)確定的。
這里我直接用阮神的例子,通過(guò)事件觸發(fā)操作,就是類(lèi)似于咱們點(diǎn)擊事件里的處理邏輯。
同樣 f1 , f2 兩個(gè)函數(shù)。
f1() f2()
f1 我們給它加一個(gè)事件,事件觸發(fā) f2 函數(shù)。
function f1(){ setTimeOut(function(){ f1.trigger("click"); }) } f1.on("click" , f2);
另外多說(shuō)點(diǎn),這上面的兩種方式都是 js 中的偽異步,而 ajax 的異步是底層多線程函數(shù)異步。
寫(xiě)在最后由于時(shí)間問(wèn)題,后續(xù)的理解會(huì)再補(bǔ)上,再理理思路。另外如果有錯(cuò)誤,也請(qǐng)各位前輩給予指正,感激不盡。
參考文獻(xiàn)http://blog.csdn.net/kobejaya...
http://www.ruanyifeng.com/blo...
https://segmentfault.com/a/11...
https://segmentfault.com/a/11...
感謝上面4篇文章的作者的辛勤付出,看完很有收獲。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/91024.html
摘要:而事件循環(huán)是主線程中執(zhí)行棧里的代碼執(zhí)行完畢之后,才開(kāi)始執(zhí)行的。由此產(chǎn)生的異步事件執(zhí)行會(huì)作為任務(wù)隊(duì)列掛在當(dāng)前循環(huán)的末尾執(zhí)行。在下,觀察者基于監(jiān)聽(tīng)事件的完成情況在下基于多線程創(chuàng)建。 主要問(wèn)題: 1、JS引擎是單線程,如何完成事件循環(huán)的? 2、定時(shí)器函數(shù)為什么計(jì)時(shí)不準(zhǔn)確? 3、回調(diào)與異步,有什么聯(lián)系和不同? 4、ES6的事件循環(huán)有什么變化?Node中呢? 5、異步控制有什么難點(diǎn)?有什么解決方...
摘要:異步請(qǐng)求線程在在連接后是通過(guò)瀏覽器新開(kāi)一個(gè)線程請(qǐng)求將檢測(cè)到狀態(tài)變更時(shí),如果設(shè)置有回調(diào)函數(shù),異步線程就產(chǎn)生狀態(tài)變更事件,將這個(gè)回調(diào)再放入事件循環(huán)隊(duì)列中。 基礎(chǔ):瀏覽器 -- 多進(jìn)程,每個(gè)tab頁(yè)獨(dú)立一個(gè)瀏覽器渲染進(jìn)程(瀏覽器內(nèi)核) 每個(gè)瀏覽器渲染進(jìn)程是多線程的,主要包括:GUI渲染線程 JS引擎線程 也稱(chēng)為JS內(nèi)核,負(fù)責(zé)處理Javascript腳本程序。(例如V8引擎) JS引擎線程負(fù)...
摘要:只要指定過(guò)這些事件的回調(diào)函數(shù),這些事件發(fā)生時(shí)就會(huì)進(jìn)入任務(wù)隊(duì)列,等待主線程讀取。異步任務(wù)必須指定回調(diào)函數(shù),當(dāng)主線程開(kāi)始執(zhí)行異步任務(wù),就是執(zhí)行對(duì)應(yīng)的回調(diào)函數(shù)。 javascript語(yǔ)言是一門(mén)單線程的語(yǔ)言,不像java語(yǔ)言,類(lèi)繼承Thread再來(lái)個(gè)thread.start就可以開(kāi)辟一個(gè)線程。所以,javascript就像一條流水線,僅僅是一條流水線而已,要么加工,要么包裝,不能同時(shí)進(jìn)行多個(gè)任...
摘要:異步那些事一基礎(chǔ)知識(shí)異步那些事二分布式事件異步那些事三異步那些事四異步那些事五異步腳本加載事件概念異步回調(diào)首先了講講中兩個(gè)方法和定義和用法方法用于在指定的毫秒數(shù)后調(diào)用函數(shù)或計(jì)算表達(dá)式。功能在事件循環(huán)的下一次循環(huán)中調(diào)用回調(diào)函數(shù)。 JS異步那些事 一 (基礎(chǔ)知識(shí))JS異步那些事 二 (分布式事件)JS異步那些事 三 (Promise)JS異步那些事 四(HTML 5 Web Workers...
摘要:的翻譯文檔由的維護(hù)很多人說(shuō),阮老師已經(jīng)有一本關(guān)于的書(shū)了入門(mén),覺(jué)得看看這本書(shū)就足夠了。前端的異步解決方案之和異步編程模式在前端開(kāi)發(fā)過(guò)程中,顯得越來(lái)越重要。為了讓編程更美好,我們就需要引入來(lái)降低異步編程的復(fù)雜性。 JavaScript Promise 迷你書(shū)(中文版) 超詳細(xì)介紹promise的gitbook,看完再不會(huì)promise...... 本書(shū)的目的是以目前還在制定中的ECMASc...
閱讀 1458·2021-09-02 19:23
閱讀 1607·2021-08-11 11:19
閱讀 652·2019-08-30 15:55
閱讀 1663·2019-08-30 12:50
閱讀 2252·2019-08-30 11:23
閱讀 2191·2019-08-29 13:13
閱讀 1511·2019-08-28 18:13
閱讀 3350·2019-08-26 11:53