目录
- 一. $.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);
});