JS基礎——異步回調

前言

一個剛入前端的小菜,雖然之前看到過關於回調的文章,可是呢,理解起來有點費勁啊。當時的腦海裏就一個概念。javascript

回調:大多出如今Ajax請求,用於處理收到的請求結果。html

嘿嘿,當時真的就是這一個想法啊。如今真的入這行,並且這個概念也很是重要,用的地方太多太多,是時候把它撿起來好好理解一番。前端

固然,本文適合菜鳥,由於我是以一個菜鳥的思惟去理解的。java

回調概念

理解一個新東西,頗有必須去理解下它的概念,由於這是最簡潔明瞭,前人總結的。ajax

A callback is a function that is passed as an argument to another function and is executed after its parent function has completed.編程

中文意思:回調是一個函數被做爲一個參數傳遞到另外一個函數裏,在那個函數執行完後再執行。
有點繞,好,我們說大白話。就是 B函數被做爲參數傳遞到A函數裏,在A函數執行完後再執行Bsegmentfault

下面我們看看代碼怎麼實現回調。瀏覽器

function A(callback){
    console.log("I am A");
    callback();  //調用該函數
}

function B(){
   console.log("I am B");
}

A(B);

這應該是最最簡單的回調了,我想你們應該明白回調的釋義了吧。
固然,這麼簡單的同步回調代碼是不會用的,現實中用都是相對比較複雜帶傳參。多線程

回調函數和異步

一開始我被回調異步有點搞暈了。還覺得回調就必定是異步的呢。
其實否則,相信上面的A,B函數的例子咱們已經明白,回調並不必定就是異步。他們本身並無直接關係。異步

下面咱們能夠理解下 同步回調異步回調(同步異步我就不單獨講了,概念很簡單)。

同步回調

就是上面的A B函數例子,它們就是同步的回調。

異步回調

由於js是單線程的,可是有不少狀況的執行步驟(ajax請求遠程數據,IO等)是很是耗時的,若是一直單線程的堵塞下去會致使程序的等待時間過長頁面失去響應,影響用戶體驗了。

如何去解決這個問題呢,咱們能夠這麼想。耗時的咱們都扔給異步去作,作好了再通知下咱們作完了,咱們拿到數據繼續往下走。

var xhr = new XMLHttpRequest();
    xhr.open('POST', url, true);   //第三個參數決定是否採用異步的方式
    xhr.send(data);
    xhr.onreadystatechange = function(){
        if(xhr.readystate === 4 && xhr.status === 200){
                ///xxxx
        }
    }

上面是一個代碼,瀏覽器在發起一個ajax請求,會單開一個線程去發起http請求,這樣的話就能把這個耗時的過程單獨去本身跑了,在這個線程的請求過程當中,readystate 的值會有個變化的過程,每一次變化就觸發一次onreadystatechange 函數,進行判斷是否正確拿到返回結果。

圖片描述

異步編程的實現

就我目前知道兩種 回調函數事件監聽 ,其實看了阮神的 異步編程的文章 和下面的評論以後得出的理解。下面我們就看看這兩種異步編程的方式吧。

回調函數

假定有三個函數

f1()

f2()

f3()

可是,f1執行很耗時,而 f2須要在f1執行完以後執行。
爲了避免影響 f3的執行,咱們能夠把f2寫成f1的回調函數。

//最原始的寫法-同步寫法

f1(); //耗時很長,嚴重堵塞
f2(); 
f3(); //致使f3執行受到影響


//改進版-異步寫法
function f1(callback){
  setTimeout(function () {
    // f1的任務代碼
    callback();
  }, 1000);
}

f1(f2); //

f3();

上面的寫法是利用 setTimeOutf1的邏輯包括起來,實現javascript中的異步編程。這樣的話,f1異步了,再也不堵塞f3的執行。
順道說下,js是單線程的,這裏所謂的異步也是僞異步,並非開了多線程的異步。它是什麼原理呢,實際上是任務棧,setTimeOut方法的原理是根據後面的定時時間,過了這個定時時間後,將f1加入任務棧,注意僅僅是加入任務棧,並非放進去就執行,而是根據任務棧裏的任務數量來肯定的。

事件監聽

這裏我直接用阮神的例子,經過事件觸發操做,就是相似於我們點擊事件裏的處理邏輯。

一樣 f1 , f2 兩個函數。

f1()

f2()

f1 咱們給它加一個事件,事件觸發 f2 函數。

function f1(){
   setTimeOut(function(){
        f1.trigger('click');
    })
}

f1.on('click' , f2);

另外多說點,這上面的兩種方式都是 js 中的僞異步,而 ajax 的異步是底層多線程函數異步。

寫在最後

因爲時間問題,後續的理解會再補上,再理理思路。另外若是有錯誤,也請各位前輩給予指正,感激涕零。

c8cbaa64034f78f0438ca6167f310a55b2191c71.jpg

參考文獻

http://blog.csdn.net/kobejaya...
http://www.ruanyifeng.com/blo...
https://segmentfault.com/a/11...
https://segmentfault.com/a/11...

感謝上面4篇文章的做者的辛勤付出,看完頗有收穫。

相關文章
相關標籤/搜索