目錄
- 一. $.ajax()返回值遇到的問題
- 二. Promise A+ 規范
- 三. 判斷是否為PromiseLike
- 3.1 判斷ES6的new Promise()
- 3.2 判斷包含then方法的對象
- 3.3 判斷$.ajax()返回的對象
一. $.ajax()返回值遇到的問題
當我們執行如下js代碼時,可以看到$.ajax()
執行后,得到的response對象并不為空,并且response對象的responseJSON屬性也確實是有值的。
但是,當我們執行response.responseJSON
后,得到的居然是undefined。
并且我們使用await 對response對象等待后,得到的就直接是response.responseJSON
中的值。
setTimeout(async () => {const response = $.ajax({url: "https://api.github.com/users/fengyehong123",type: 'GET',});console.log(response);console.log(response.responseJSON); // undefinedconst result = await response;console.log(result);}, 1000);
?執行效果如下:
🤔上述現象是因為 $.ajax()
得到的對象是一個 Promise Like
對象,Promise Like
對象和ES6的new Promise()
一樣,都是對 Promise A+
規范的實現,因此可以使用 await
進行等待。
二. Promise A+ 規范
官網: https://promisesaplus.com/
ES6的new Promise()
也好,$.ajax()函數返回的Promise Like
對象也好,
都只是Promise A+
規范的一種實現,該規范告訴我們如何自己實現一個Promise。
三. 判斷是否為PromiseLike
?如果一個值的類型為 object 或者 function
并且 該值還存在一個then方法
那么 該值就是一個 PromiseLike 對象。
// 判斷是否為 Promise Likefunction isPromiseLike(value) {if(value === null) {return false;}if ((typeof value === 'object' || typeof value === 'function') && (typeof value.then === 'function')){return true;}return false;
}
3.1 判斷ES6的new Promise()
?ES6 的 new Promise() 是 Promise A+
規范的實現,所以肯定是一個 PromiseLike 對象
const promise_obj = new Promise((resolve, reject) => {resolve('楓葉紅');
});
console.log(isPromiseLike(promise_obj) ? "promise_obj是PromiseLike對象" : "promise_obj非PromiseLike對象");
3.2 判斷包含then方法的對象
?定義一個對象,對象里面有一個then方法
,方法里面是耗時操作。符合該對象是一個Promise Like
對象。
const then_response = {then: function(resolve, reject) {setTimeout(() => {resolve('賈飛天');}, 1000)}
}
console.log(isPromiseLike(then_response) ? "then_response是PromiseLike對象" : "then_response非PromiseLike對象"
);
// then_response是PromiseLike對象(async (response) => {/*此處的response實際上是then_response因為 then_response 是一個 Promise Like 對象要想await的話,必須包裹在 函數中因此此處定義了一個立即執行函數,還可以避免給函數取名的麻煩*/const result = await response;console.log(result);
})(then_response);
3.3 判斷$.ajax()返回的對象
// ?兩秒之后發送ajax請求
setTimeout(async () => {const response = $.ajax({url: "https://api.github.com/users/fengyehong123",type: 'GET',});// 是一個PromiseLike對象console.log(isPromiseLike(response) ? "response是PromiseLike對象" : "response非PromiseLike對象");// response是PromiseLike對象// 正因為是 PromiseLike對象 ,所以才可以進行awaitconst result = await response;console.log(result);
}, 2000);
?也就是說,我們之后的$.ajax()函數可以這么寫
// ajax的請求對象
const jqRequest = $.ajax({url,method: 'GET'
});// doneCallBack,failCallBack,alwaysCallback 是從外部傳入的回調函數
jqRequest.done(function(data, textStatus, jqXHR) {doneCallBack && doneCallBack(data);
}).fail(function(jqXHR, textStatus, errorThrown) {failCallBack && failCallBack();
}).always(function() {alwaysCallback && alwaysCallback();
});
?也可以這么寫,從而可以避免回調的方式
document.querySelector('#btn').addEventListener('click', async function() {const url = "https://api.github.com/users/fengyehong123";// 后端的返回值let result = null;try {result = await $.ajax({url,type: 'GET',});} catch (error) {const {responseJSON} = error;console.log(`請求失敗!原因是: ${responseJSON}`);} finally {console.log("請求完成!");}if(!result) {// 進行相應的業務處理return;}console.log("返回的最終值為:");console.log(result);
});