JS PromiseLike的判定与使用详解
作者:fengyehongWorld
一. $.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); });
到此这篇关于JS PromiseLike的判定与使用详解的文章就介绍到这了,更多相关JS PromiseLike内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!