摘要:可信任性確定性在解決上述的回調(diào)函數(shù)的問題之前,有必要先來認識一下的一些主要方法的起點執(zhí)行結(jié)果依次是,,,代碼解讀以上代碼體現(xiàn)了的如下特性一旦決議調(diào)用過一次或者就不再重復(fù)調(diào)用決議回調(diào)或者改變決議回調(diào)。
通過回調(diào)來理解Promise
我們都知道Promise的出現(xiàn)是為了規(guī)避回調(diào)地獄的,由此,我們先來深入了解一下回調(diào)的缺陷:
回調(diào)1、缺乏信任
2、不確定性
Example
var money = 30; order(money,function getOrder(orderId){ // order是一個第三方的下訂單的回調(diào)函數(shù) orderId && pay(orderId); // 獲取訂單編號之后調(diào)用第三方支付pay方法去付款 }) // ...同步代碼
代碼解讀:上面的代碼只是常規(guī)代碼中的一部分,其中order是一個第三方下訂單的方法,需要攜帶回調(diào)函數(shù)過去獲取訂單編號,這里面就存在一些信任性和不確定性的問題,如:
1、有可能回調(diào)函數(shù)getOrder始終不會被調(diào)用,那我們就永遠拿不到訂單編號去支付;
2、有可能回調(diào)了,可是回調(diào)了不止一次,導(dǎo)致我們重復(fù)去支付了;
3、不確定回掉時間,有可能立馬回調(diào),那么接下來的同步代碼就會在回調(diào)之后執(zhí)行,有可能它內(nèi)部調(diào)用了異步代碼再回調(diào),那么接下來的同步代碼就會在回調(diào)之前執(zhí)行。
4、也有可能下訂單的第三方模塊自己內(nèi)部出錯了,導(dǎo)致我們沒辦法捕獲異常;
上面只是回調(diào)的一部分缺陷,但其實當(dāng)我們不喜歡一個東西的時候總有這么多理由,當(dāng)我們喜歡一個東西的時候,沒有理由也會找一堆理由的,下面就是Promise的理由。
Promise1、可信任性
2、確定性
在解決上述的回調(diào)函數(shù)的問題之前,有必要先來認識一下Promise的一些主要方法:
1、Promise的起點new Promise()Example
console.log(1); let promise = new Promise(function PromiseBack(resolve,reject){ resolve(); resolve(); reject(); reject(); console.log(2); }).then(()=>{ console.log(4); },()=>{ console.log(5); }) console.log(3); // 執(zhí)行結(jié)果依次是:1,2,3,4
代碼解讀:以上代碼體現(xiàn)了new Promise的如下特性:
2、多Promise同時執(zhí)行:Promise.all([ .. ])1、一旦決議(調(diào)用過一次resolve或者reject)就不再重復(fù)調(diào)用決議回調(diào)或者改變決議回調(diào)。
2、決議代碼是同步的,可是決議的成功或失敗的回調(diào)代碼一定是異步的,而且Promise的異步實現(xiàn)比setTimeout的調(diào)用時間更早,因為回調(diào)決議存在于Event loop的microtask隊列中。
Example
let promise1 = new Promise(function(resolve,reject){ resolve(1); }); let promise2 = new Promise(function(resolve,reject){ resolve(2); // reject(3); }); let promise3 = Promise.all([promise1,promise2]).then(function resolveBack(result){ console.log(result); // 打印結(jié)果是:[ 1, 2 ] },function rejectBack(result){ console.log(result); // 當(dāng)promise2注釋部分放開,非注釋部分注釋,打印結(jié)果是:3 })
代碼解讀:Promise.all方法對于promise數(shù)組的決議是:當(dāng)其中所有的promise都是成功決議的時候,就會調(diào)用成功的決議回調(diào)resolveBack,并且把promise數(shù)組的決議值以數(shù)組的形式按照順序返回resolve中的值;如果其中哪怕有一個失敗的決議都會調(diào)用失敗的決議回調(diào)rejectBack,并且只返回promise宿主中失敗的決議值,以數(shù)組順序返回。
3、多Promise競賽執(zhí)行:Promise.race([ .. ])Example
let promise1 = new Promise(function(resolve,reject){ setTimeout(function(){ resolve(1); },100); }); let promise2 = new Promise(function(resolve,reject){ setTimeout(function(){ //resolve(2); reject(3); },50); }); let promise3 = Promise.race([promise1,promise2]).then(function resolveBack(result){ console.log(result); // 打印結(jié)果是:2 },function rejectBack(result){ console.log(result); // 當(dāng)promise2注釋部分放開,非注釋部分注釋,打印結(jié)果是:3 })
代碼解讀:Promise.race方法和all方法不同,它對于promise數(shù)組的決議是:當(dāng)promise數(shù)組中有一個成功了,那就會立即執(zhí)行成功的決議回調(diào),當(dāng)有一個失敗了,就會立即執(zhí)行失敗的決議回調(diào),所以,它也叫競賽決議,它的一個常用的應(yīng)用場景就是異步請求超時處理,代碼如下:
Example:
// request(..)是一個支持Promise的Ajax工具 let promise1 = request( "http://some.url.1/"); let promise2 = function(second=1000){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ reject("請求超時"); },second) }) }; let promise3 = Promise.race([promise1,promise2(3000)]) .then(function resolveBack(result){ console.log(result); },function rejectBack(result){ console.log(result); // 當(dāng)請求超時3秒鐘就決議失敗,打印錯誤信息,如果這里信息是統(tǒng)一處理,那最好超時的值構(gòu)造成和異步請求返回錯誤結(jié)果的值一致 })4、Promise錯誤處理catch...
Example
new Promise((resolve,reject)=>{ console.log(a); }).catch((err)=>{ console.log(err); // 打印結(jié)果:33 [ReferenceError: a is not defined] })
代碼解讀:catch和then一樣都是Promise的實例方法,而且也都調(diào)用完成之后也都會返回一個新的Promise實例,這樣就可以繼續(xù)then或catch了,這也就是Promise的“鏈?zhǔn)搅鳌?/strong>。其實catch本身實現(xiàn)和then是類似的,可以完全看成是then僅有失敗決議回調(diào),即:then(null,(err)=>{})。也就是說then的失敗決議當(dāng)Promise決議代碼出錯了,哪怕沒有調(diào)用reject方法,也是會被捕獲到錯誤的。
總結(jié)瀏覽過上述方法之后,我們現(xiàn)在來解決一開始我們遇到的那個回調(diào)函數(shù)的問題,解決問題代碼如下:
Example
var money = 30; let promise1 = new Promise(function(resolve,reject){ order(money,function getOrder(orderId){ orderId ? resolve(orderId) : reject(orderId); }); }); let promise2 = function(second=1000){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ reject("請求超時"); },second) }) }; let promise3 = Promise.race([promise1,promise2(3000)]) .then(function resolveBack(result){ console.log(result); },function rejectBack(result){ console.log(result); // 當(dāng)請求超時,或者order內(nèi)部代碼錯誤等都會調(diào)用失敗的決議 }) // ...同步代碼
代碼解讀:上面這個Promise例子展示了對回調(diào)問題的規(guī)避,具體解決思路是:
1、通過使用Promise.race競賽決議方法解決如果第三方的order方法不調(diào)用getOrder的情況,可以定位到具體的錯誤代碼和錯誤原因;
2、根據(jù)Promise的決議特性:一旦決議不可狀態(tài)不可更改,不可重復(fù)。解決了回調(diào)了不止一次的問題;
3、根據(jù)Promise的決議回調(diào)是異步的特性,決議的回調(diào)一定是異步的特性,解決了回調(diào)時間的不確定性。
4、根據(jù)rejectBack類似catch的特性,失敗的決議回調(diào)是可以捕獲到?jīng)Q議代碼異常的報錯的,那這樣,如果第三方內(nèi)部出現(xiàn)了問題,是可以捕獲到的。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/84610.html
摘要:直到最近,我們?nèi)匀辉谟煤唵蔚幕卣{(diào)函數(shù)來處理異步的問題。當(dāng)我們只有一個異步任務(wù)的時候使用回調(diào)函數(shù)看起來還不會有什么問題。 原文地址:http://blog.getify.com/promis... 廈門旅行歸來,繼續(xù)理解Promise 在上一篇深入理解Promise五部曲:1.異步問題中,我們揭示了JS的異步事件輪詢并發(fā)模型并且解釋了多任務(wù)是如何相互穿插使得它們看起來像是同時運行的。...
摘要:的翻譯文檔由的維護很多人說,阮老師已經(jīng)有一本關(guān)于的書了入門,覺得看看這本書就足夠了。前端的異步解決方案之和異步編程模式在前端開發(fā)過程中,顯得越來越重要。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。 JavaScript Promise 迷你書(中文版) 超詳細介紹promise的gitbook,看完再不會promise...... 本書的目的是以目前還在制定中的ECMASc...
摘要:理解回調(diào)和原文自工程師博客,傳送門這兩個概念是編程語言的基本內(nèi)容?;卣{(diào)地獄就是濫用回調(diào)。通常,在回調(diào)中,錯誤作為第一個參數(shù)傳遞。這個具有這兩個函數(shù)作為參數(shù)的回調(diào)稱為執(zhí)行程序。到目前為止,我希望我已經(jīng)讓自己了解了回調(diào)和。 理解回調(diào)和Promise 原文自工程師Fernando Hernandez博客,傳送門 這兩個概念是Javascript編程語言的基本內(nèi)容。因為這種語言是在異步編程的...
摘要:從源碼看概念與實現(xiàn)是異步編程中的重要概念,它較好地解決了異步任務(wù)中回調(diào)嵌套的問題。這些概念中有趣的地方在于,標(biāo)識狀態(tài)的變量如都是形容詞,用于傳入數(shù)據(jù)的接口如與都是動詞,而用于傳入回調(diào)函數(shù)的接口如及則在語義上用于修飾動詞的副詞。 從源碼看 Promise 概念與實現(xiàn) Promise 是 JS 異步編程中的重要概念,它較好地解決了異步任務(wù)中回調(diào)嵌套的問題。在沒有引入新的語言機制的前提下,這...
摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。寫一個符合規(guī)范并可配合使用的寫一個符合規(guī)范并可配合使用的理解的工作原理采用回調(diào)函數(shù)來處理異步編程。 JavaScript怎么使用循環(huán)代替(異步)遞歸 問題描述 在開發(fā)過程中,遇到一個需求:在系統(tǒng)初始化時通過http獲取一個第三方服務(wù)器端的列表,第三方服務(wù)器提供了一個接口,可通過...
閱讀 3790·2023-04-25 21:09
閱讀 3136·2021-10-20 13:48
閱讀 3044·2021-09-24 10:25
閱讀 2942·2021-08-21 14:08
閱讀 1800·2019-08-30 15:56
閱讀 989·2019-08-30 15:52
閱讀 1856·2019-08-29 14:11
閱讀 3575·2019-08-29 11:01