日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

一道有意思并对你有帮助的Promise题

發(fā)布時間:2023/12/20 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一道有意思并对你有帮助的Promise题 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一道有意思的題

以下我的學(xué)習(xí)分析心路歷程,以及我自己又多加了幾道菜;希望對你有幫助

先上菜

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ù)制代碼

分析第一道菜

  • 第一次看到我做錯了,答案是
promise1 then11 promise2 then21 then12 then23 復(fù)制代碼
  • 我的疑惑就是then12為什么在then21和then23之前,很奇怪。說明什么呢?我對Promise的內(nèi)部實現(xiàn)還不了解,那只能去看源碼了。在學(xué)習(xí)過程中,自己也嘗試改變了幾處,也貼上來吧,大家看看

看完后我的理解

先分析下面代碼

new Promise((resolve, reject) => {console.log('promise1');resolve(); }) 復(fù)制代碼
  • 第一步console.log('promise1'),這是第一個promise實例

  • 第二步resolve(),他是一個異步,放入異步隊列中,取名異步1

  • 第三步this.status 狀態(tài)是pending 接著執(zhí)行下面代碼

.then(() => {console.log('then11');new Promise((resolve, reject) => {console.log('promise2');resolve();}).then(() => {console.log('then21');}).then(() => {console.log('then23');}); }) 復(fù)制代碼
  • 因為狀態(tài)是pending,將then方法回調(diào)函數(shù)加入執(zhí)行隊列(一個數(shù)組)等待執(zhí)行(專用來放then方法的數(shù)組),該then方法取名方法1

重點接著執(zhí)行什么?

并不是執(zhí)行.then(() => {console.log(then12)}),要記住的是then的參數(shù)方法執(zhí)行時機是當(dāng)前(屬于自己的)promise狀態(tài)改變才會執(zhí)行,誰改變resolve或者rejectd的執(zhí)行,那么這里then的promise哪里來,就是上面的方法1中來看他的return值 所以開始執(zhí)行異步1(我都有取名的,看?),第一個promise實例狀態(tài)變?yōu)镕ULFILLED

  • 首先resolve()參數(shù)為undefind不是一個promise類型,所以執(zhí)行執(zhí)行隊列(一個數(shù)組),即方法1,也就是第一個then`的參數(shù)
  • 因為狀態(tài)改變所以開始執(zhí)行方法1
() => {console.log('then11');new Promise((resolve, reject) => {console.log('promise2');resolve(); //新的resolve 取名異步2}).then(() => { console.log('then21');}).then(() => {console.log('then23');}); } 復(fù)制代碼
  • 第一步打印console.log('then11');
  • 又新建了一個Promise,打印console.log('promise2');
  • resolve();又一個異步,放入異步隊列中,取名異步2
  • 然后因為新的promise它的狀態(tài)是pengding,所以() => {console.log('then21');}方法放入新的promise的執(zhí)行隊列的數(shù)組中(和上面一樣專用來放then方法的數(shù)組)
  • 同理后面的then并不回執(zhí)行,它需要等待新的resolve的執(zhí)行,來改變狀態(tài)執(zhí)行then

重點2

  • 因為方法1的沒有return,即return 一個undefined,但我們都知道then會默認(rèn)返回一個return new Promise((resolve, reject) => {})對象,所以這時候他是執(zhí)行了的一個異步操作resolve()取名異步3,
  • 所以有了這個異步3,這個return的promise的狀態(tài)為pending,所以then(() => {console.log(then12)})加入到(專用來放then方法的數(shù)組)的執(zhí)行回調(diào)數(shù)組中

然后開始執(zhí)行異步隊列的函數(shù),有兩個異步2和異步3,先執(zhí)行異步2,接下來的操作和重點2是一樣的又會return new Promise((resolve, reject) => {}),又會有一個異步4resolve(),接著講then方法放入數(shù)組中,等待resolve()改變promise狀態(tài)來執(zhí)行then方法

  • 所以在等待期間會執(zhí)行異步3,然后打印console.log(then12)
  • 最后打印console.log(then23)

總結(jié)要點

  • then(func)執(zhí)行時機是等待一個與它相關(guān)的promise的狀態(tài)改變
  • then(func)中的func默認(rèn)會return new Promise((resolve, reject) => {resolve()})用于下一個then(func)
  • 如果我們手動return 一個promise結(jié)果就會不同,看下面例子

再變個花樣

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ù)制代碼

分析

  • 看到一個then(func)中我們直接返回了一個promise,所以先加入第一異步2,并且要等待它相關(guān)的promise狀態(tài)改變,但是它狀態(tài)改變了,那就是等異步2的執(zhí)行,一旦執(zhí)行,接著就是() =>{console.log('then23'); //默認(rèn)resolve() 異步4}的執(zhí)行了,所以異步4先一步比異步5加入,也就先執(zhí)行了,
  • 所以結(jié)果就是
promise1 then11 promise2 then21 then23 then12 復(fù)制代碼

我再來變個樣

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ù)制代碼

分析一下這幾個異步就要能知道答案了

  • console.log('promise1');
  • 先加入異步1, 執(zhí)行后輸出console.log('then11'); console.log('promise2');
  • 在加入異步2, 再加入異步5
  • 先執(zhí)行異步2, console.log('then21'); 并將加入異步4
  • 再執(zhí)行異步5, 但這個異步和下面的then不相關(guān),因為這邊隱藏的會再下加入一個resolve()(即異步6) 即這個異步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题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。