一道有意思并对你有帮助的Promise题
一道有意思的題
以下我的學(xué)習(xí)分析心路歷程,以及我自己又多加了幾道菜;希望對(duì)你有幫助
先上菜
new Promise((resolve, reject) => {console.log('promise1');resolve(); }).then(() => {console.log('then11');new Promise((resolve, reject) => {console.log('promise2');resolve();}).then(() => {console.log('then21');}).then(() => {console.log('then23');}); }).then(() => {console.log('then12'); });復(fù)制代碼分析第一道菜
- 第一次看到我做錯(cuò)了,答案是
- 我的疑惑就是then12為什么在then21和then23之前,很奇怪。說(shuō)明什么呢?我對(duì)Promise的內(nèi)部實(shí)現(xiàn)還不了解,那只能去看源碼了。在學(xué)習(xí)過(guò)程中,自己也嘗試改變了幾處,也貼上來(lái)吧,大家看看
看完后我的理解
先分析下面代碼
new Promise((resolve, reject) => {console.log('promise1');resolve(); }) 復(fù)制代碼-
第一步console.log('promise1'),這是第一個(gè)promise實(shí)例
-
第二步resolve(),他是一個(gè)異步,放入異步隊(duì)列中,取名異步1
-
第三步this.status 狀態(tài)是pending 接著執(zhí)行下面代碼
- 因?yàn)闋顟B(tài)是pending,將then方法回調(diào)函數(shù)加入執(zhí)行隊(duì)列(一個(gè)數(shù)組)等待執(zhí)行(專(zhuān)用來(lái)放then方法的數(shù)組),該then方法取名方法1
重點(diǎn)接著執(zhí)行什么?
并不是執(zhí)行.then(() => {console.log(then12)}),要記住的是then的參數(shù)方法執(zhí)行時(shí)機(jī)是當(dāng)前(屬于自己的)promise狀態(tài)改變才會(huì)執(zhí)行,誰(shuí)改變r(jià)esolve或者rejectd的執(zhí)行,那么這里then的promise哪里來(lái),就是上面的方法1中來(lái)看他的return值 所以開(kāi)始執(zhí)行異步1(我都有取名的,看?),第一個(gè)promise實(shí)例狀態(tài)變?yōu)镕ULFILLED
- 首先resolve()參數(shù)為undefind不是一個(gè)promise類(lèi)型,所以執(zhí)行執(zhí)行隊(duì)列(一個(gè)數(shù)組),即方法1,也就是第一個(gè)then`的參數(shù)
- 因?yàn)闋顟B(tài)改變所以開(kāi)始執(zhí)行方法1
- 第一步打印console.log('then11');
- 又新建了一個(gè)Promise,打印console.log('promise2');
- resolve();又一個(gè)異步,放入異步隊(duì)列中,取名異步2
- 然后因?yàn)樾碌膒romise它的狀態(tài)是pengding,所以() => {console.log('then21');}方法放入新的promise的執(zhí)行隊(duì)列的數(shù)組中(和上面一樣專(zhuān)用來(lái)放then方法的數(shù)組)
- 同理后面的then并不回執(zhí)行,它需要等待新的resolve的執(zhí)行,來(lái)改變狀態(tài)執(zhí)行then
重點(diǎn)2
- 因?yàn)榉椒?的沒(méi)有return,即return 一個(gè)undefined,但我們都知道then會(huì)默認(rèn)返回一個(gè)return new Promise((resolve, reject) => {})對(duì)象,所以這時(shí)候他是執(zhí)行了的一個(gè)異步操作resolve()取名異步3,
- 所以有了這個(gè)異步3,這個(gè)return的promise的狀態(tài)為pending,所以then(() => {console.log(then12)})加入到(專(zhuān)用來(lái)放then方法的數(shù)組)的執(zhí)行回調(diào)數(shù)組中
然后開(kāi)始執(zhí)行異步隊(duì)列的函數(shù),有兩個(gè)異步2和異步3,先執(zhí)行異步2,接下來(lái)的操作和重點(diǎn)2是一樣的又會(huì)return new Promise((resolve, reject) => {}),又會(huì)有一個(gè)異步4resolve(),接著講then方法放入數(shù)組中,等待resolve()改變promise狀態(tài)來(lái)執(zhí)行then方法
- 所以在等待期間會(huì)執(zhí)行異步3,然后打印console.log(then12)
- 最后打印console.log(then23)
總結(jié)要點(diǎn)
- then(func)執(zhí)行時(shí)機(jī)是等待一個(gè)與它相關(guān)的promise的狀態(tài)改變
- then(func)中的func默認(rèn)會(huì)return new Promise((resolve, reject) => {resolve()})用于下一個(gè)then(func)
- 如果我們手動(dòng)return 一個(gè)promise結(jié)果就會(huì)不同,看下面例子
再變個(gè)花樣
new Promise((resolve, reject) => {console.log('promise1');resolve(); //異步1 }).then(() => {console.log('then11');return new Promise((resolve, reject) => {console.log('promise2');resolve(); //異步2 }).then(() => {console.log('then21');//默認(rèn)resolve() 異步3}).then(() => {console.log('then23');//默認(rèn)resolve() 異步4}); }).then(() => {console.log('then12'); }); 復(fù)制代碼分析
- 看到一個(gè)then(func)中我們直接返回了一個(gè)promise,所以先加入第一異步2,并且要等待它相關(guān)的promise狀態(tài)改變,但是它狀態(tài)改變了,那就是等異步2的執(zhí)行,一旦執(zhí)行,接著就是() =>{console.log('then23'); //默認(rèn)resolve() 異步4}的執(zhí)行了,所以異步4先一步比異步5加入,也就先執(zhí)行了,
- 所以結(jié)果就是
我再來(lái)變個(gè)樣
new Promise((resolve, reject) => {console.log('promise1');resolve(); //異步1 }).then(() => {console.log('then11');new Promise((resolve, reject) => {console.log('promise2');resolve(); //異步2}).then(() => {console.log('then21'); //異步3}).then(() => {console.log('then23');//異步4});return Promise.resolve(1) //異步5 }).then(() => {console.log('then12'); }); 復(fù)制代碼分析一下這幾個(gè)異步就要能知道答案了
- console.log('promise1');
- 先加入異步1, 執(zhí)行后輸出console.log('then11'); console.log('promise2');
- 在加入異步2, 再加入異步5
- 先執(zhí)行異步2, console.log('then21'); 并將加入異步4
- 再執(zhí)行異步5, 但這個(gè)異步和下面的then不相關(guān),因?yàn)檫@邊隱藏的會(huì)再下加入一個(gè)resolve()(即異步6) 即這個(gè)異步5是這樣的resolve().then(res => { ... //resolve() 異步6 })
- 接著先執(zhí)行異步4, 輸出console.log('then23');
- 接著先執(zhí)行異步6, 輸出console.log('then12');
同樣發(fā)布在segmentfault
轉(zhuǎn)載于:https://juejin.im/post/5cde586651882525a20fd3cd
總結(jié)
以上是生活随笔為你收集整理的一道有意思并对你有帮助的Promise题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 多元线性回归分析示例
- 下一篇: 【2022/01/27】thinkphp