jquery中Ajax的異步和同步

版權聲明: 本文由 一隻博客 發表於 bloghome博客javascript

文章連接: https://www.bloghome.com.cn/user/cnn237111java

jquery中默認的ajax調用方法是異步的,所以稍不注意就會出錯。好比有一個例子,要求經過ajax檢查一個數是奇數仍是偶數。某人不加思索的寫出以下的代碼:jquery

$(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"}。ajax

寫下這樣的代碼後,運行後獲得的結果以下:json

clipboard

這是由於success方法裏面的return,僅僅是對success方法的返回值,而不是checkodd的返回值,這樣的返回值是沒法直接由checkodd方法作獲得的。瀏覽器

所以,某人修改代碼以下:app

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的值。async

jquery的ajax提供了async參數,經過設置該參數的值爲false,能夠避免異步執行。所以,某人再次修改代碼:ide

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比較費勁,能夠看下面的代碼。

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處理這個事件。

相關文章
相關標籤/搜索