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