在一個頁面中,我們可能會使用多個初始化加載函數,包括可能有onload、$(document).ready(function (e) {});。
他們的具體差別不在該文章中涉及,本篇主要分析一下ajax的請求狀態及異步同步處理,多個ajax請求的狀態監控和分析。
ajax帶來很好的用戶體驗,於是一個稍微注重web系統使用ajax基本成爲必然。當傳統功能型web項目向用戶體驗型項目轉變時,
-
層出不窮的需求就來了。正如本篇所介紹的就是一個多個AJAX請求的情況下,如何利用jquery來處理幾種case。
-
多個ajax請求同時發送,相互無依賴。
-
多個ajax請求相互依賴,必須有先後順序。
-
多個請求被同時發送,只需要最後一個請求。
第1種case
應用場景: 這個場景很多,一個頁面打開是多個區域同時請求後臺得到各自的數據,沒依賴,沒順序。
處理方案: 直接用jquery的ajax函數。這個用的非常多,這裏從略,可看後面的代碼中例子。
第2種case
應用場景: 多個ajax請求,需要順序執行,後一個ajax請求的執行參數是前一個ajax的結果。例如:
用戶登錄後我們發送一次請求得到用戶的應用ID,然後利用應用ID發送一次請求得到具體的應用內容
(例子雖然不是太恰當,但基本就是這個意思了)。
處理方法:
1. 利用ajax參數async設置爲false,進行同步操作。(這個方法只適合同域操作,跨域需使用下面兩種方法)
2. 利用ajax嵌套(這個同第1種情況)
3. 利用隊列進行操作
1)、ajax請求實際上和http正常的頁面打開是一樣的返回代碼,具體代碼查看:
2)、頁面多個ajax請求時,我們如何監控每個ajax的執行情況?
這裏是有辦法的,如果是一個單獨的界面我們可以在每個ajax的函數中處理:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
$.ajax({ type: "post" , dataType: "json" , traditional: true , data: { oper: "detail" , id: id }, url: AjaxUrl, success: function (data, textStatus) { if (data != null ) { //成功處理 } }, complete: function (XMLHttpRequest, textStatus) { //完成處理 }, error: function (e) { //異常處理 } }); |
但是,要是很多頁面都需要統一處理,或者需要等到所有ajax請求完成後,才處理下一步請求,就需要有一個監控
該頁面所有ajax請求完成情況的全局處理了。這個可以使用jQuery自帶的ajax全局變量進行處理。
背景介紹:Jquery ajax全局變量
jquery 提供了一個列表 全局Ajax事件處理程序 。 這些全局事件是發起每一個AJAX請求時產生。如果全局變量jQuery.ajaxSetup()是true。
默認情況下它是true。
-
.ajaxStart——註冊一個處理程序被稱爲第一個AJAX請求時開始;每個頁面中所有的ajax請求只發生一次。
-
.ajaxSend——附加一個函數執行之前發送一個AJAX請求;每次發起ajax請求就觸發一次。
-
.ajaxError——註冊一個處理程序被稱爲AJAX請求完成時一個錯誤;
-
.ajaxSuccess——附加一個函數執行時一個AJAX請求成功完成;
-
.ajaxComplete——註冊一個處理程序被稱爲AJAX請求完成;每次發起一次ajaxsend請求就對應一次complete。
-
.ajaxStop——註冊一個處理程序被稱爲當所有AJAX請求已經完成了。
每當一個Ajax請求即將發送,jQuery檢查是否有任何其他響應過程中的Ajax請求。如果沒有檢查到,jQuery就會觸發ajaxStart事件。
我們可以使用上面的事件註冊程序,把一些通用操作所有AJAX請求在這些事件中簡化和統一處理。
一些可能用到的場景如下:
-
顯示一個繁忙的圖標和阻塞UI每當一個AJAX請求的過程;
-
不管碰到一個AJAX錯誤顯示一條錯誤消息;
-
重定向用戶重定向到登錄頁面如果web會話到期時一個AJAX請求。
-
監控多個ajax的狀態執行情況
-
在頁面所有ajaxsend執行完成後,執行下一步的操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
var sendcount = 0; var completecount = 0; // 添加ajax全局事件處理。 $(document).ajaxStart( function (a,b,c) { }).ajaxSend( function (e, xhr, opts) { sendcount++; }).ajaxError( function (e, xhr, opts) { }).ajaxSuccess( function (e, xhr, opts) { }).ajaxComplete( function (e, xhr, opts) { completecount++; if (sendcount == completecount) { //進行下一步操作 } }).ajaxStop( function () { }); |
2)、異步和同步的差別:
$.ajax()其中有一個參數爲async: false,false爲同步。
ajax是調用xmlhttprequest對象之類(以ie爲例)發送請求,而這些對象本來就有併發數的限制,不同的瀏覽器也是不同的數目限制,ie貌似是2。
有一點要注意,Javascript自身是單線程運行的,所有的主流瀏覽器只提供一個線程執行Javascript。因此Javascript不能開啓額外的線程(除非使用Web Workers,目前最新的瀏覽器 Safari, Chrome, Opera and Mozilla Firefox支持Web Workers,IE10也會支持)。Javascript中的事件都是線性執行的,通過一個任務隊列,可以近似的看做先進先出的模式處理事件的,因此所有的Javascript異步實現都是假象,通過計時器實現的。
Javascript自身單線程運行,不代表ajax是單線程運行,因爲ajax是通過XMLHttpRequest這個API實現的,因此是瀏覽器提供額外的線程去處理http request。一旦請求處理完畢,它會觸發一個事件,把這個事件加入到javascript任務隊列中,直到javascript處理這個事件。
3)、ajax不執行Success的問題
-
JQuery 中Ajax的一點其它的認識: 客戶端發起請求,得到服務器端的相應是200,<正確拿到服務器響應的數據>沒有問題.此時在判斷進入success 對應的回調函數還是進入到error對應的回調函數之前,可能會校驗一些東西:
1. 返回的每條數據是否是dataType中定義的數據類型。如果有部分數據不是或者哪怕一條數據沒有嚴格的按照dataType定義的類型,程序就會進入到error:function(){****}
2. 請求的域和當前域是否是同一域,如果不是同一域也十分有可能進入error:function(){***}
參考代碼:
An Example to Use jQuery Global AJAX Event Handlers - CodeProject
多ajax請求的各類解決方案(同步, 隊列, cancel請求)的令一種解決方案 - 參禪 - 博客園
http://www.cnblogs.com/spnt/archive/2013/03/21/2973970.html
轉載:IT分享 http://www.suchso.com