主頁 > 知識庫 > 網頁基礎 > Javascript/Ajax >
欄目列表

jquery中Ajax的異步和同步

來源:網絡 作者:佚名 發表于:2012-11-06 14:32  點擊:
jquery中默認的ajax調用方法是異步的,因此稍不注意就會出錯。比如有一個例子,要求通過ajax檢查一個數是奇數還是偶數。某人不加思索的寫出如下的代碼: 雙擊代碼全選 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 $( function
jquery中默認的ajax調用方法是異步的,因此稍不注意就會出錯。比如有一個例子,要求通過ajax檢查一個數是奇數還是偶數。某人不加思索的寫出如下的代碼:
雙擊代碼全選
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$(function () {     
    $("#btntest").click( function(){     
        var s=checkodd(5);     
        alert(s);     
    });     
});     
           
function checkodd(i) {     
    var options = {     
        type: 'POST',     
        url: "test.ashx",     
        data: { "i": i },     
        success: function (result) {     
            if (result.code > 0) {     
                return "odd";     
            }     
            else {     
                return "even";     
            }     
        },     
        dataType: "json",     
        error: function (result) {     
            alert("error");     
        }     
    };     
    $.ajax(options);      
}
 
其中test.ashx會在接到請求后,如果傳入的i是奇數則返回json格式的數據{"code":"1"},如果是偶數,則返回{"code":"-1"}。
寫下這樣的代碼后,運行后得到的結果如下:
clipboard
這是因為success方法里面的return,僅僅是對success方法的返回值,而不是checkodd的返回值,這樣的返回值是無法直接由checkodd方法做得到的。
因此,某人修改代碼如下:
雙擊代碼全選
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function checkodd(i) {     
    var returnvalue;     
    var options = {     
        type: 'POST',     
        url: "test.ashx",     
        data: { "i": i },     
        success: function (result) {     
            if (result.code > 0) {     
                returnvalue = "odd";     
            }     
            else {     
                returnvalue = "even";     
            }     
        },     
        dataType: "json",     
        error: function (result) {     
            alert("error");     
        }     
    };     
    $.ajax(options);      
    return returnvalue;     
}
 
通過一個中間變量returnvalue來獲取返回值。看上去還不錯。但是運行后得到的結果卻是:
clipboard[1]
原因很簡單,忽略了ajax默認情況下是異步執行的,也就是說,在ajax方法沒有運行完,即success方法都沒運行完成之前,已經將returnvalue的值返回出去了,那當然就得到undefined的值。
jquery的ajax提供了async參數,通過設置該參數的值為false,可以避免異步執行。因此,某人再次修改代碼:
雙擊代碼全選
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function checkodd(i) {     
    var returnvalue;     
    var options = {     
        type: 'POST',     
        url: "test.ashx",     
        data: { "i": i },     
        async:false,     
        success: function (result) {     
            if (result.code > 0) {     
                returnvalue = "odd";     
            }     
            else {     
                returnvalue = "even";     
            }     
        },     
        dataType: "json",     
        error: function (result) {     
            alert("error");     
        }     
    };     
    $.ajax(options);      
    return returnvalue;     
}
 
這次終于對了。
clipboard[2]
async:false這樣設置,使得ajax必須執行完成后,才可執行下面的代碼,因此在適當的情況下,要修改ajax的參數來保證同步運行。
事 實上,jquery的ajax本質上調用了XMLHttpRequest對象。XMLHttpRequest是一個API,各個瀏覽器對它都有各自的實 現。比如老版本的IE用的是ActiveX, Firefox使用XMLHttpRequest對象。這個API主要實現javascript進行HTTP(S)通信。詳細的說明可以參與維基百科 http://en.wikipedia.org/wiki/XMLHttpRequest。
直接使用該API實現ajax比較費勁,可以看下面的代碼。
雙擊代碼全選
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function useXMLHttpRequest() {     
    var xmlhttp = new XMLHttpRequest();     
    xmlhttp.open("POST", "test.ashx", false);     
    xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");     
    xmlhttp.onreadystatechange = function () {     
        if (xmlhttp.readyState == 4) {     
            //alert(xmlhttp.responseText);     
            if (xmlhttp.responseText.code > 0) {     
                alert("odd");     
            }     
            else {     
                alert("even");     
            }     
        }     
    };     
    xmlhttp.send("i=5");     
    alert("finished");     
}
 
上 面的代碼實現了前面jquery的ajax的功能,編寫起來比較麻煩,要設置一些參數等等,其中xmlhttp.open("POST", "test.ashx", false);中,最后的參數false或者true是控制ajax為同步還是異步,和前面的jquery的ajax例子中的一個意思。所以jquery 對該API做了包裝,使得用jquery操作ajax更方便。
有一點要注意,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處理這個事件。
本文出自 “一只博客” 博客,請務必保留此出處http://cnn237111.blog.51cto.com/2359144/1038080
 

    有幫助
    (4)
    57.1%
    沒幫助
    (3)
    42.9%
    欧美多p性群交换