JS PromiseLike的判定與使用詳解
一. $.ajax()返回值遇到的問題
當(dāng)我們執(zhí)行如下js代碼時(shí),可以看到$.ajax()
執(zhí)行后,得到的response對(duì)象并不為空,并且response對(duì)象的responseJSON屬性也確實(shí)是有值的。
但是,當(dāng)我們執(zhí)行response.responseJSON
后,得到的居然是undefined。
并且我們使用await 對(duì)response對(duì)象等待后,得到的就直接是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);
執(zhí)行效果如下:
上述現(xiàn)象是因?yàn)?nbsp;$.ajax()
得到的對(duì)象是一個(gè) Promise Like
對(duì)象,Promise Like
對(duì)象和ES6的new Promise()
一樣,都是對(duì) Promise A+
規(guī)范的實(shí)現(xiàn),因此可以使用 await
進(jìn)行等待。
二. Promise A+ 規(guī)范
官網(wǎng): https://promisesaplus.com/
ES6的new Promise()
也好,$.ajax()函數(shù)返回的Promise Like
對(duì)象也好,
都只是Promise A+
規(guī)范的一種實(shí)現(xiàn),該規(guī)范告訴我們?nèi)绾巫约簩?shí)現(xiàn)一個(gè)Promise。
三. 判斷是否為PromiseLike
如果一個(gè)值的類型為 object 或者 function并且 該值還存在一個(gè)then方法那么 該值就是一個(gè) PromiseLike 對(duì)象。
// 判斷是否為 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+
規(guī)范的實(shí)現(xiàn),所以肯定是一個(gè) PromiseLike 對(duì)象
const promise_obj = new Promise((resolve, reject) => { resolve('楓葉紅'); }); console.log(isPromiseLike(promise_obj) ? "promise_obj是PromiseLike對(duì)象" : "promise_obj非PromiseLike對(duì)象");
3.2 判斷包含then方法的對(duì)象
定義一個(gè)對(duì)象,對(duì)象里面有一個(gè)then方法
,方法里面是耗時(shí)操作。符合該對(duì)象是一個(gè)Promise Like
對(duì)象。
const then_response = { then: function(resolve, reject) { setTimeout(() => { resolve('賈飛天'); }, 1000) } } console.log( isPromiseLike(then_response) ? "then_response是PromiseLike對(duì)象" : "then_response非PromiseLike對(duì)象" ); // then_response是PromiseLike對(duì)象 (async (response) => { /* 此處的response實(shí)際上是then_response 因?yàn)?then_response 是一個(gè) Promise Like 對(duì)象 要想await的話,必須包裹在 函數(shù)中 因此此處定義了一個(gè)立即執(zhí)行函數(shù),還可以避免給函數(shù)取名的麻煩 */ const result = await response; console.log(result); })(then_response);
3.3 判斷$.ajax()返回的對(duì)象
// ?兩秒之后發(fā)送ajax請(qǐng)求 setTimeout(async () => { const response = $.ajax({ url: "https://api.github.com/users/fengyehong123", type: 'GET', }); // 是一個(gè)PromiseLike對(duì)象 console.log( isPromiseLike(response) ? "response是PromiseLike對(duì)象" : "response非PromiseLike對(duì)象" ); // response是PromiseLike對(duì)象 // 正因?yàn)槭?PromiseLike對(duì)象 ,所以才可以進(jìn)行await const result = await response; console.log(result); }, 2000);
也就是說,我們之后的$.ajax()函數(shù)可以這么寫
// ajax的請(qǐng)求對(duì)象 const jqRequest = $.ajax({ url, method: 'GET' }); // doneCallBack,failCallBack,alwaysCallback 是從外部傳入的回調(diào)函數(shù) jqRequest.done(function(data, textStatus, jqXHR) { doneCallBack && doneCallBack(data); }).fail(function(jqXHR, textStatus, errorThrown) { failCallBack && failCallBack(); }).always(function() { alwaysCallback && alwaysCallback(); });
也可以這么寫,從而可以避免回調(diào)的方式
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(`請(qǐng)求失敗!原因是: ${responseJSON}`); } finally { console.log("請(qǐng)求完成!"); } if(!result) { // 進(jìn)行相應(yīng)的業(yè)務(wù)處理 return; } console.log("返回的最終值為:"); console.log(result); });
到此這篇關(guān)于JS PromiseLike的判定與使用詳解的文章就介紹到這了,更多相關(guān)JS PromiseLike內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 深入探討JavaScript異步編程中Promise的關(guān)鍵要點(diǎn)
- 詳解JavaScript中Promise的原理與應(yīng)用
- JavaScript使用Promise控制并發(fā)請(qǐng)求
- 在JavaScript中使用Promise.allSettled()的方法
- Javascript?promise.all的用法介紹(簡潔易懂)
- 詳解如何使用JavaScript中Promise類實(shí)現(xiàn)并發(fā)任務(wù)控制
- JS手搓P(guān)romise的常見方法總結(jié)
- 使用Promise和JavaScript有效處理1000個(gè)請(qǐng)求的方法
- JavaScript 中使用Promise.all()方法經(jīng)驗(yàn)技巧詳解
相關(guān)文章
原生JS實(shí)現(xiàn)H5轉(zhuǎn)盤游戲的示例代碼
這篇文章主要介紹了如何利用原生JS實(shí)現(xiàn)轉(zhuǎn)盤游戲,可以自由調(diào)整概率。文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)JavaScript有一定幫助,需要的可以參考一下2022-03-03spirngmvc js傳遞復(fù)雜json參數(shù)到controller的實(shí)例
下面小編就為大家分享一篇spirngmvc js傳遞復(fù)雜json參數(shù)到controller的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-03-03神級(jí)程序員JavaScript300行代碼搞定漢字轉(zhuǎn)拼音
這篇文章主要介紹了神級(jí)程序員JavaScript300行代碼搞定漢字轉(zhuǎn)拼音,需要的朋友可以參考下2017-05-05對(duì)table和ul實(shí)現(xiàn)js分頁示例分享
本文主要介紹了js對(duì)table和ul li實(shí)現(xiàn)前臺(tái)分頁,需要的朋友可以參考下2014-02-02javascript實(shí)現(xiàn)炫酷的拖動(dòng)分頁
非常酷的javascript拖動(dòng)分頁功能,無縫循環(huán)分頁,拖動(dòng)鼠標(biāo)即可完成分頁,鼠標(biāo)向左拖動(dòng)回到前一頁,向右拖動(dòng)則翻開第二頁,還帶有動(dòng)畫特效,著實(shí)很不錯(cuò),界面黑色,非主流風(fēng)格,相信很多人會(huì)喜歡的。2015-05-05利用JS對(duì)iframe父子(內(nèi)外)頁面進(jìn)行操作的方法教程
這篇文章主要給大家介紹了利用JS對(duì)iframe父子(內(nèi)外)頁面進(jìn)行操作的方法教程,其中包括了怎么對(duì)iframe進(jìn)行操作、在iframe里面控制iframe外面的js代碼以及在父框架對(duì)子iframe進(jìn)行操作等,需要的朋友可以參考借鑒。2017-06-06JsRender for index循環(huán)索引用法詳解
這篇文章主要介紹了JsRender for index循環(huán)索引用法,以實(shí)例形式詳細(xì)分析了JsRender中循環(huán)的用法,需要的朋友可以參考下2014-10-10