最近項目裏遇到ajax異步性的問題,簡化後的代碼以下:html
function ajaxGetEvents(calendarView, time) { var year = time.getFullYear(); var month = time.getMonth() + 1 < 10 ? "0" + (time.getMonth() + 1) : time.getMonth() + 1; var day = time.getDate() < 10 ? "0" + time.getDate() : time.getDate(); var timeStr = year + "-" + month + "-" + day; var ajaxData = { search_monthNum : timeStr; }; var ajaxUrl = localStorage.getItem("globalUrl") + 'trip/sheduleInfo!monthList.action'; var eventsData; $.ajax( { type : 'post', dataType : 'json', url : ajaxUrl, data : ajaxData, async: false,//此處設置ajax爲同步請求 success : function(data) { if (data.retCode == '1') { eventsData = data.returnData; } else { console.log(data.message); } }, error : function() { console.log('ajax error in calendar.js'); } }); return eventsData; }
這個函數試圖將ajax獲取到的數據存儲到eventsData中,而後返回。html5
這裏主要要注意的是註釋處,若是不將這個請求設爲同步請求的話,這個返回的數據永遠都會是空的。git
異步的ajax是非阻塞的,success回調函數只在數據返回後纔開始執行,而在此以前,程序會繼續運行,執行return語句,那麼被返回的eventsData永遠是空的。ajax
而同步請求是阻塞的,將這個函數中的請求設爲同步則能夠解決問題,代價是執行這個函數時可能會須要等待一段時間,時間的長短天然是看響應的速度了。json
此外,相似的還有html5中的定位方法geolocation,看下面代碼:瀏覽器
$(function(){ var lat, lng; getCurrPosition(); $('#position').html("lat = " + lat + ' lng = ' + lng); function getCurrPosition(){ if(navigator.geolocation){ navigator.geolocation.getCurrentPosition(getPositionSuccess, getPositionError); }else{ alert("您的瀏覽器不支持Geolocation!"); } } function getPositionSuccess(position) { lat = position.coords.latitude; lng = position.coords.longitude; } function getPositionError(error){ switch (error.code) { case error.TIMEOUT: alert("鏈接超時,請重試"); break; case error.PERMISSION_DENIED: alert("您拒絕了使用位置共享服務,查詢已取消"); break; case error.POSITION_UNAVAILABLE: alert("位置信息不可用"); break; } } });
geolocation中的getCurrentPosition和watchPosition也都是異步的方法,像這個程序試圖顯示座標信息的作法也是不可行的,lat和lng會一直爲空。異步
而這裏就沒辦法像ajax同樣設爲同步了,可行的作法應該是將進行顯示的語句$("#position").html()放在getPositionSuccess函數中。async