目录
- 一. $.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); // undefined
const 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 Like
function 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对象 ,所以才可以进行await
const 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);
});