摘要:問題前端小同學在做頁面的時候,犯了個常見的錯誤把多個請求順序著寫下來了,而后面的請求,對前面請求的返回結果,是有依賴的。經提醒,發現從版開始,返回的就是對象了,那么函數可以直接返回的返回值
問題
前端小同學在做頁面的時候,犯了個常見的錯誤:把多個Ajax請求順序著寫下來了,而后面的請求,對前面請求的返回結果,是有依賴的。如下面的代碼所示:
var someData; $.ajax({ url: "/prefix/entity1/action1", type: "GET" , async: true, contentType: "application/json", success: function (resp) { //do something on response someData.attr1 = resp.attr1; }, error: function (XMLHttpRequest, textStatus, errorThrown) { //在這個頁面里,所有的請求的錯誤都做同樣的處理 if (XMLHttpRequest.status == "401") { window.location.href = "/login.html"; } else { alert(XMLHttpRequest.responseText); } } }); $.ajax({ url: "/prefix/entity2/action2", type: "POST" , dataType: "json", data: JSON.stringify(someData), async: true, contentType: "application/json", success: function (resp) { //do something on response }, error: function (XMLHttpRequest, textStatus, errorThrown) { //在這個頁面里,所有的請求的錯誤都做同樣的處理 if (XMLHttpRequest.status == "401") { window.location.href = "/login.html"; } else { alert(XMLHttpRequest.responseText); } } });
以上代碼有兩個問題:
*首先就是執行順序不能保證,action2很可能在action1返回之前就發出了,導致someData.attr1這個參數沒能正確傳出
*其次兩個ajax請求的代碼重復很嚴重
代碼重復的問題相對好解決,尤其是在自己的項目里,各種參數可以通過規范定死,封裝一個參數更少的ajax方法就好了
//url:地址 //data:數據對象,在函數內部會轉化成json串,如果沒傳,表示用GET方法,如果傳了,表示用POST方法 function ajax(url, data, callback) { $.ajax({ url: url, type: data == null ? "GET" : "POST", dataType: "json", data: data == null ? "" : JSON.stringify(data), async: true, contentType: "application/json", success: function (resp) { callback(resp); }, error: function (XMLHttpRequest, textStatus, errorThrown) { if (XMLHttpRequest.status == "401") { window.parent.location = "/enterprise/enterprise_login.html"; self.location = "/enterprise/enterprise_login.html"; } else { alert(XMLHttpRequest.responseText); } } }); }
這樣只有url,data和callback三個必要的參數要填,其他都定死了
執行順序的問題,可以把第二個請求放在第一個請求的回調里,形如:
ajax("/prefix/entity1/action1",null, function(resp){ //do something on response someData.attr1 = resp.attr1; ajax("/prefix/entity2/action2", someData, function(resp){ //do something on response } };
至此問題似乎解決得很完美,但可以想見,如果請求不止兩個,而是4、5個,同時還有其他異步操作(比如我們的頁面里有Vue對象的初始化),相互之間有依賴關系,光是這樣層層疊疊的括號嵌套,就已經讓人頭暈了。
需要找到一種方法,讓異步調用的表達看起來像同步調用一樣。
正好最近看了阮一峰老師關于ES6的書,而且用戶也沒有強硬要求兼容IE瀏覽器,于是就選擇了Promise的方案
解決方案引入Promise
其實現代瀏覽器都已經內置支持了Promise,連第三方庫都不需要了,只有IE不行,放棄了
改造ajax封裝函數,在成功的時候調用resolve(),失敗的時候調用reject(),并且返回Promise對象
function ajax(url, data, callback) { var p = new Promise(function (resolve, reject) { $.ajax({ url: url, type: data == null ? "GET" : "POST", dataType: "json", data: data == null ? "" : JSON.stringify(data), async: true, contentType: "application/json", success: function (resp) { callback(resp); resolve(); }, error: function (XMLHttpRequest, textStatus, errorThrown) { if (XMLHttpRequest.status == "401") { window.parent.location = "/enterprise/enterprise_login.html"; self.location = "/enterprise/enterprise_login.html"; } else { alert(XMLHttpRequest.responseText); } reject(); } }); }); return p; }
修改調用端
ajax("/prefix/entity1/action1",null, function(resp){ //do something on response someData.attr1 = resp.attr1; }).then( ajax("/prefix/entity2/action2", someData, function(resp){ //do something on response } ).then( initVue() ; ).then( //do something else )
至此完美解決。
經@miroki 提醒,發現Jquery從1.5版開始,返回的就是thenable對象了,那么ajax函數可以直接返回$.ajax()的返回值
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/81769.html
摘要:引擎線程也稱為內核,負責處理腳本程序例如引擎引擎線程負責解析腳本,運行代碼。對象代表一個未完成但預計將來會完成的操作。注意一旦新建就會立即執行它屬于,無法取消。 寫在前面: 第一遍學Promise時, 只是大概過了一遍, 感覺學的不夠深入, 這一篇算是對之前的一個總結吧. Promise在ES6中也屬于一個較難理解的一部分; 所以在學習一個比較難理解的知識點時, 我們可以圍繞這個知識點...
摘要:簽訂協議的兩方分別是異步接口和。在異步函數中,使用異常捕獲的方案,代替了的異常捕獲的方案。需要注意的是,在異步函數中使異步函數用時要使用,不然異步函會被同步執行。 同步與異步 通常,代碼是由上往下依次執行的。如果有多個任務,就必需排隊,前一個任務完成,后一個任務才會執行。這種執行模式稱之為: 同步(synchronous) 。新手容易把計算機用語中的同步,和日常用語中的同步弄混淆。如,...
摘要:從源碼看概念與實現是異步編程中的重要概念,它較好地解決了異步任務中回調嵌套的問題。這些概念中有趣的地方在于,標識狀態的變量如都是形容詞,用于傳入數據的接口如與都是動詞,而用于傳入回調函數的接口如及則在語義上用于修飾動詞的副詞。 從源碼看 Promise 概念與實現 Promise 是 JS 異步編程中的重要概念,它較好地解決了異步任務中回調嵌套的問題。在沒有引入新的語言機制的前提下,這...
摘要:異步請求線程在在連接后是通過瀏覽器新開一個線程請求將檢測到狀態變更時,如果設置有回調函數,異步線程就產生狀態變更事件,將這個回調再放入事件循環隊列中。 基礎:瀏覽器 -- 多進程,每個tab頁獨立一個瀏覽器渲染進程(瀏覽器內核) 每個瀏覽器渲染進程是多線程的,主要包括:GUI渲染線程 JS引擎線程 也稱為JS內核,負責處理Javascript腳本程序。(例如V8引擎) JS引擎線程負...
摘要:能幫我們解決什么痛點實現異步執行,在未出現前,我們通常是使用嵌套的回調函數來解決的。那么,接下來我們看一下使用的實例可以傳入兩個參數表示兩個狀態的回調函數,第一個是,必選參數第二個是,可選參數的方便之處。 深入理解promise 對于現在的前端同學來說你不同promise你都不好意思出門了。對于前端同學來說promise已經成為了我們的必備技能。 那么,下面我們就來說一說promise...
閱讀 3082·2021-09-28 09:43
閱讀 915·2021-09-08 09:35
閱讀 1452·2019-08-30 15:56
閱讀 1197·2019-08-30 13:00
閱讀 2744·2019-08-29 18:35
閱讀 1838·2019-08-29 14:07
閱讀 3446·2019-08-29 13:13
閱讀 1343·2019-08-29 12:40