Promise中的then鏈機制用法詳解
Promise中的then鏈機制
因為每一次 .then都會返回一個新的promise實例,所以我們就可以持續(xù) .then下去了
而且因為實例誕生的方式不同,所以狀態(tài)判斷標準也不同
- 第一類:new Promise出來的實例
- 執(zhí)行的是:resolve還是reject決定狀態(tài)
- executor函數(shù)執(zhí)行是否報錯
- 第二類:.then返回的新實例 (不論執(zhí)行的是onfulfilled還是onrejected)
- 首先看返回值是否為新的promise實例,如果不是,則只看執(zhí)行是否報錯(不報錯狀態(tài)就是成功,值就是函數(shù)返回值;報錯則狀態(tài)就是失敗,值就是失敗原因)
- 如果返回的是新promise實例(@p),這樣@p這個promise實例是成功還是失敗,直接決定了.then產(chǎn)生這個實例是成功還是失敗。但是如果@p是成功狀態(tài),需要把它的值再次處理一遍(值如果是一個新的promise實例,并且其狀態(tài)是失敗,那么最終會以這個新實例的狀態(tài)為主)...如果@p是失敗的,直接認定為失敗的狀態(tài),不需要把失敗的值再處理了。
- 第三類:
- Promise.resolve(100) 返回一個狀態(tài)是成功,值是100的新promise實例
- Promise.reject(0) 返回一個狀態(tài)是失敗,值是0的新promise實例
只要實例的狀態(tài)和值我們分析好,則.then(onfulfilled,onrejected)存放的兩個方法哪一個執(zhí)行,我們就知道了
then鏈的穿透性(順延)
正常情況下,.then的時候會傳遞兩個函數(shù)onfulfilled/onrejected,但是有些時候,我們是不傳遞其中的某個函數(shù)的,這種情況下我們需要采取“順延策略”:找到下一個then中對應狀態(tài)的函數(shù)執(zhí)行
例如:.then(null,onrejected) 或者 .then(onfulfilled);
.then中的異步
promise.then(onfulfilled,onrejected)
- 情況一:此時已經(jīng)知道promise是成功還是失敗的
- 我們應該去執(zhí)行onfulfilled或者onrejected,但是不是立即執(zhí)行,它是一個異步的微任務
- 首先,把執(zhí)行對應的方法這個事情放在WebAPI中監(jiān)聽,但是因為此時已經(jīng)知道狀態(tài)了,對應的方法可以執(zhí)行,所以緊接著把它挪至到EventQueue中(異步微任務隊列)等待執(zhí)行。
- 情況二:此時的promise還是pending狀態(tài)
- 我們把onfulfilled或者onrejected先存儲起來,只有當后面我們把實例的狀態(tài)修改為成功/失敗的時候,再取出之前存儲的方法,把其執(zhí)行【而且此時再執(zhí)行,還是個異步微任務】
- 還是要經(jīng)歷:WebAPI -> EventQueue
catch
真實項目中,我們經(jīng)常.then中只傳遞onfulfilled,處理狀態(tài)是成功的事情;在then鏈的末尾設置一個catch,處理失敗的事情(依托于then鏈的穿透機制,無論最開始的還是哪個then中,出現(xiàn)了讓狀態(tài)為失敗的情況,都會順延到最末尾的catch部分)
Promise.all
//異步的“并行”:同時處理,相互之間互不影響 fn1().then(result => { console.log(result); }); fn2().then(result => { console.log(result); }); fn3().then(result => { console.log(result); });
并行中的綜合處理:一起發(fā)送多個請求(處理多個異步),但是需要等到所有異步都成功,我們在整體做啥事?。?/p>
let promise = Promise.all([promise1,promise2,...]);
- 執(zhí)行Promise.all返回一個新的promise實例@p
- 并且傳遞一個數(shù)組,數(shù)組中包含n多其他的promise實例
- 如果數(shù)組中的每一個promise實例最后都是成功狀態(tài)的,則@p也會是成功的,它的值也是一個數(shù)組,按照“最開始的順序”(不會考慮誰先成功)依次存儲各個promise實例的結果;但凡數(shù)組中的某個promise實例是失敗的(只要遇到一個失敗的,后面不在處理了)。則@p也是失敗的,值是當前這個實例失敗的原因!
- 如果數(shù)組中有一項并不是promise實例(例如:是個100),則瀏覽器也會把其默認變?yōu)橐粋€狀態(tài)是成功的promise實例,值就是當前項本身。
async
async修飾符:修飾一個函數(shù),讓函數(shù)的返回值成為一個promise實例,這樣就可以基于THEN鏈去處理了
- 如果函數(shù)自己本身就返回一個promise實例,則以自己返回的為主
- 如果函數(shù)自己本身沒有返回promise,則會把返回值變?yōu)橐粋€promise實例:狀態(tài) -> 成功,值 -> 返回值
- 如果函數(shù)執(zhí)行報錯,則返回的實例,狀態(tài) -> 成功,值 -> 報錯原因
async最主要的作用就是:如果想在函數(shù)中使用await,則當前函數(shù)必須基于async修飾。
await
等待,一般在其后面放promise實例,它會等待實例狀態(tài)為成功,再去執(zhí)行“當前上下文”await下面的代碼【如果promise實例管控的是一個異步編程,其實他是在等待異步執(zhí)行成功,再執(zhí)行下面代碼,類似于異步改為同步效果】
如果后面放的不是promise實例,則瀏覽器默認會把其轉換為“狀態(tài)為成功,值就是這個值”的實例
await 10; --> await Promise.resolve(10);
以上就是Promise中的then鏈機制用法詳解的詳細內(nèi)容,更多關于Promise then鏈機制的資料請關注腳本之家其它相關文章!
相關文章
JavaScript中window和document用法詳解
這篇文章主要介紹了JavaScript中window和document用法詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-07-07WEB前端開發(fā)框架Bootstrap3 VS Foundation5
WEB前端開發(fā)框架Bootstrap3 VS Foundation5,這篇文章主要介紹了Bootstrap3與Foundation5的五大區(qū)別,感興趣的小伙伴們可以參考一下2016-05-05