Ajax非同步回撥函式(callback)
ajax請求確實是非同步的,不過這請求是由瀏覽器新開一個執行緒請求,當請求的狀態變更時,如果先前已設定回撥,這非同步執行緒就產生狀態變更事件放到 JavaScript引擎的處理佇列中等待處理。見:http://www.phpv.net/html/1700.html
你有事去隔壁寢室找同學,發現人不在,你怎麼辦呢?
方法1,每隔幾分鐘再去趟隔壁寢室,看人在不
方法2,拜託與他同寢室的人,看到他回來時叫一下你
前者是輪詢,後者是回撥。
那你說,我直接在隔壁寢室等到同學回來可以嗎?
可以啊,只不過這樣原本你可以省下時間做其他事,現在必須浪費在等待上了。把原來的非阻塞的非同步呼叫變成了阻塞的同步呼叫。
JavaScript的回撥是在非同步呼叫場景下使用的,使用回撥效能好於輪詢。
“我現在出發,到了通知你” 這是一個非同步的流程,“我出發”這個過程中(函式執行),“你”可以去做任何事,“到了”(函式執行完畢)“通知你”(回撥)進行之後的流程。
函式也是物件
想弄明白回撥函式,首先的清楚地明白函式的規則。在javascript中,函式是比較奇怪的,但它確確實實是物件。確切地說,函式是用Function()建構函式建立的Function物件。Function物件包含一個字串,字串包含函式的javascript程式碼。假如你是從C語言或者java語言轉過來的,這也許看起來很奇怪,程式碼怎麼可能是字串?但是對於javascript來說,這很平常。資料和程式碼之間的區別是很模糊的。
傳統函式以引數形式輸入資料,並且使用返回語句返回值。理論上,在函式結尾處有一個return返回語句,結構上就是:一個輸入點和一個輸出點。這比較容易理解,函式本質上就是輸入和輸出之間實現過程的對映。
但是,當函式的實現過程非常漫長,你是選擇等待函式完成處理,還是使用回撥函式進行非同步處理呢?這種情況下,使用回撥函式變得至關重要,例如:AJAX請求。若是使用回撥函式進行處理,程式碼就可以繼續進行其他任務,而無需空等。實際開發中,經常在javascript中使用非同步呼叫,甚至在這裡強烈推薦使用!
下面有個更加全面的使用AJAX載入XML檔案的示例,並且使用了call()函式,在請求物件(requested object)上下文中呼叫回撥函式。
從《Head First Ajax》理解關於回撥函式
回撥函式是一個函式的引用,不是呼叫,所以應確保不要在函式名後加上括號。
問:你能再解釋一下什麼是回撥函式嗎?
答:回撥函式是另外某件事結束時執行的一個函式。在Ajax中,回撥函式就是伺服器對一個請求物件作出響應時呼叫的函式。瀏覽器會在某個時刻”回撥”這個函式。
問:那就是說,當伺服器結束對一個請求的處理時就會執行一個回撥函式,對嗎?
答:不是這樣的,實際上每次伺服器響應請求時就會由瀏覽器呼叫回撥函式,即使此時伺服器並沒有完全處理完請求。大多數伺服器都會做多次響應,指示接收到請求,或者正在處理請求,或者已經處理完請求。
問:就是因為這個原因,這個請求屬性才被命名為onreadystatechange嗎?
答:完全正確。每次伺服器響應一個請求時,它會把請求物件readyState屬性設定為一個不同的值。所以我們要特別注意這個屬性,來確定伺服器何時處理完我們傳送給它的請求。
問:這麼說來,處理完請求時伺服器會呼叫displayDetails(),是嗎?
答:不對,實際上是由瀏覽器呼叫這個函式。伺服器所做的只是更新請求物件的readyState屬性。每次這個屬性發生變化時,瀏覽器就會呼叫onreadystatechange屬性中指定的函式。
問:readyState屬性是什麼?
答:這是一個數,指示伺服器處理進行到哪個階段。初始值為0,伺服器處理完一個請求時,這個屬性的值將是4.
問:為什麼每一次都必須檢查呢?
答:因為每次準備狀態改變時瀏覽器都會執行回撥函式。由於伺服器接收到請求時會把這個值設定為1,而在處理請求時有可能把這個值設定為2或3,所以除非readyState等於4,否則無法確定伺服器是否處理完請求。
問:那麼status屬性呢?
答:這是HTTP狀態碼,如404就代表禁止訪問,200代表成功。對請求物件做任何處理之前一定要確保狀態碼為200。
使用Ajax非同步呼叫的時候,
需要觸發readystatechange事件,然後檢測readyState屬性即可。這個屬性有五個值:
當請求傳送到伺服器端, 收到響應後, 響應的資料會自動填充 XHR物件的屬性。 那麼一共有四個屬性:
接受響應之後, 第一步檢查 status屬性, 以確定響應已經成功返回。 一般而已 HTTP狀
態程式碼為 200作為成功的標誌。除了成功的狀態程式碼,還有一些別的: