成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

深入理解promise對(duì)象

CoderDock / 1613人閱讀

摘要:前言中的異步,剛開(kāi)始的時(shí)候都是用回調(diào)函數(shù)實(shí)現(xiàn)的,所以如果異步嵌套的話,就有出現(xiàn)回調(diào)地獄,使得代碼難以閱讀和難以維護(hù),后來(lái)出現(xiàn)了,解決了回調(diào)地獄的問(wèn)題。

前言

js中的異步,剛開(kāi)始的時(shí)候都是用回調(diào)函數(shù)實(shí)現(xiàn)的,所以如果異步嵌套的話,就有出現(xiàn)回調(diào)地獄,使得代碼難以閱讀和難以維護(hù),后來(lái)es6出現(xiàn)了promise,解決了回調(diào)地獄的問(wèn)題。現(xiàn)在我們就自己寫(xiě)代碼實(shí)現(xiàn)一下promise,這樣才能深入理解promise的運(yùn)行機(jī)制,對(duì)以后使用promise也能夠更加得心應(yīng)手。開(kāi)始之前可以先看下promise的官網(wǎng)
promise/A+

先來(lái)看下promise的用法

</>復(fù)制代碼

  1. new Promise((resolve,reject)=>{
  2. resolve(1);
  3. reject(11);
  4. }).then(res=>{
  5. console.log(res);
  6. setTimeout(()=>{
  7. return new Promise((resolve,reject)=>{
  8. resolve(2)
  9. })
  10. },1000)
  11. }).then(res2=>{
  12. console.log(res2);
  13. });

控制臺(tái)打印
1
...1s later
2

先分析下上面這段代碼,先提出幾個(gè)問(wèn)題
1.第一段resolve和reject都有,但是只輸出了1,為什么?
2.then里的res是如何取到resolve中的值的?
3.promise是如何做到鏈?zhǔn)秸{(diào)用的?

狀態(tài)機(jī)

promise中有個(gè)狀態(tài)機(jī)的概念,先說(shuō)下為什么要有狀態(tài)機(jī)的概念呢,因?yàn)閜romise的狀態(tài)是單向變化的,有三種狀態(tài),pending,fullfilled,rejected,而這三種狀態(tài)只能從pending->fullfilled或者pending->rejected這兩種形式,也就是說(shuō)執(zhí)行了fullfilled之后,就不會(huì)執(zhí)行rejected。這就解釋了上面的第一個(gè)問(wèn)題。

下面我們來(lái)看下具體實(shí)現(xiàn)的完整代碼

</>復(fù)制代碼

  1. const PENDING = "PENDING";
  2. const FULLFILLED = "FULLFILLED";
  3. const REJECTED = "REJECTED";
  4. class Promise{
  5. constructor(fn){
  6. this.status = PENDING;//狀態(tài)
  7. this.data = undefined;//返回值
  8. this.defercb = [];//回調(diào)函數(shù)數(shù)組
  9. //執(zhí)行promise的參數(shù)函數(shù),并把resolve和reject的this綁定到promise的this
  10. fn(this.resolve.bind(this),this.reject.bind(this));
  11. }
  12. resolve(value){
  13. if(this.status === PENDING){
  14. //只能pending=>fullfied
  15. this.status = FULLFILLED;
  16. this.data = value;
  17. this.defercb.map(item=>item.onFullFilled());
  18. }
  19. }
  20. reject(value){
  21. if(this.status === PENDING){
  22. //只能pending=>rejected
  23. this.status = REJECTED;
  24. this.data = value;
  25. this.defercb.map(item=>item.onRejected());
  26. }
  27. }
  28. then(resolveThen,rejectThen){
  29. //如果沒(méi)有resolveThen方法,保證值可以穿透到下一個(gè)then里有resolveThen的方法中
  30. resolveThen = typeof resolveThen === "function" ? resolveThen : function(v) {return v};
  31. rejectThen = typeof rejectThen === "function" ? rejectThen : function(r) {return r};
  32. //返回的都是promise對(duì)象,這樣就可以保證鏈?zhǔn)秸{(diào)用了
  33. switch(this.status){
  34. case PENDING:
  35. return new Promise((resolve,reject)=>{
  36. const onFullFilled = () => {
  37. const result = resolveThen(this.data);//這里調(diào)用外部then的resolveThen方法,將值傳回去
  38. //如果返回值是promise對(duì)象,執(zhí)行then方法,取它的結(jié)果作為新的promise實(shí)例的結(jié)果,因?yàn)閠his.data會(huì)重新賦值
  39. result instanceof Promise && result.then(resolve,reject);
  40. }
  41. const onRejected = ()=>{
  42. const result = rejectThen(this.data);
  43. result instanceof Promise && result.then(resolve,reject);
  44. }
  45. this.defercb.push({onFullFilled,onRejected});
  46. });
  47. break;
  48. case FULLFILLED:
  49. return new Promise((resolve,reject)=>{
  50. const result = resolveThen(this.data);
  51. result instanceof Promise && result.then(resolve,reject);
  52. resolve(result);
  53. })
  54. break;
  55. case REJECTED:
  56. return new Promise((resolve,reject)=>{
  57. const result = rejectThen(this.data);
  58. result instanceof Promise && result.then(resolve,reject);
  59. reject(result)
  60. })
  61. break;
  62. }
  63. }
  64. }

運(yùn)行下面的例子

</>復(fù)制代碼

  1. new Promise((resolve, reject) => {
  2. setTimeout(() => {
  3. resolve(1);
  4. }, 1000);
  5. }).then((res2) => {
  6. console.log(res2);
  7. return new Promise((resolve, reject) => {
  8. setTimeout(() => {
  9. resolve(2);
  10. }, 1000);
  11. });
  12. }).then((res3) => {
  13. console.log(res3);
  14. return new Promise((resolve, reject) => {
  15. setTimeout(() => {
  16. resolve(3);
  17. }, 1000);
  18. });
  19. }).then((res4) => {
  20. console.log(res4);
  21. });

控制臺(tái)打印
...1s later
1
...1s later
2
...1s later
3
說(shuō)明上面的實(shí)現(xiàn)是沒(méi)有問(wèn)題的
不過(guò)還有一個(gè)問(wèn)題,就是事件循環(huán)的順序問(wèn)題,比如執(zhí)行下面的代碼

</>復(fù)制代碼

  1. new Promise((resolve) => {
  2. resolve();
  3. })
  4. .then(() => {
  5. console.log("1");
  6. })
  7. .then(() => {
  8. console.log("2");
  9. });
  10. console.log("3");

并沒(méi)有像預(yù)想中輸出3,1,2,而是輸出了1,2,3,原因就是因?yàn)槲覀兊倪@個(gè)Promise是在主線程中,沒(méi)有在下一個(gè)任務(wù)隊(duì)列中,可以加上settimeout解決這個(gè)問(wèn)題,不過(guò)這也只是為了讓我們更好理解執(zhí)行順序而已,然而實(shí)際上是promise是屬于微任務(wù)中的,而settimeout是屬于宏任務(wù),還是不太一樣的

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/99315.html

相關(guān)文章

  • [譯] 深入理解 Promise 五部曲:4. 擴(kuò)展問(wèn)題

    摘要:有一個(gè)和相關(guān)的更大的問(wèn)題。最后,請(qǐng)負(fù)有責(zé)任感并且使用安全的擴(kuò)展。深入理解五部曲異步問(wèn)題深入理解五部曲轉(zhuǎn)換問(wèn)題深入理解五部曲可靠性問(wèn)題深入理解五部曲擴(kuò)展性問(wèn)題深入理解五部曲樂(lè)高問(wèn)題最后,安利下我的個(gè)人博客,歡迎訪問(wèn) 原文地址:http://blog.getify.com/promis... 現(xiàn)在,我希望你已經(jīng)看過(guò)深入理解Promise的前三篇文章了。并且假設(shè)你已經(jīng)完全理解Promises...

    Shimmer 評(píng)論0 收藏0
  • ES6-7

    摘要:的翻譯文檔由的維護(hù)很多人說(shuō),阮老師已經(jīng)有一本關(guān)于的書(shū)了入門(mén),覺(jué)得看看這本書(shū)就足夠了。前端的異步解決方案之和異步編程模式在前端開(kāi)發(fā)過(guò)程中,顯得越來(lái)越重要。為了讓編程更美好,我們就需要引入來(lái)降低異步編程的復(fù)雜性。 JavaScript Promise 迷你書(shū)(中文版) 超詳細(xì)介紹promise的gitbook,看完再不會(huì)promise...... 本書(shū)的目的是以目前還在制定中的ECMASc...

    mudiyouyou 評(píng)論0 收藏0
  • JavaScript 異步

    摘要:從最開(kāi)始的到封裝后的都在試圖解決異步編程過(guò)程中的問(wèn)題。為了讓編程更美好,我們就需要引入來(lái)降低異步編程的復(fù)雜性。寫(xiě)一個(gè)符合規(guī)范并可配合使用的寫(xiě)一個(gè)符合規(guī)范并可配合使用的理解的工作原理采用回調(diào)函數(shù)來(lái)處理異步編程。 JavaScript怎么使用循環(huán)代替(異步)遞歸 問(wèn)題描述 在開(kāi)發(fā)過(guò)程中,遇到一個(gè)需求:在系統(tǒng)初始化時(shí)通過(guò)http獲取一個(gè)第三方服務(wù)器端的列表,第三方服務(wù)器提供了一個(gè)接口,可通過(guò)...

    tuniutech 評(píng)論0 收藏0
  • [譯] 深入理解 Promise 五部曲:3. 可靠性問(wèn)題

    摘要:簡(jiǎn)單的說(shuō),即將到來(lái)的標(biāo)準(zhǔn)指出是一個(gè),所以作為一個(gè),必須可以被子類(lèi)化。保護(hù)還是子類(lèi)化這是個(gè)問(wèn)題我真的希望我能創(chuàng)建一個(gè)忠實(shí)的給及以下。 原文地址:http://blog.getify.com/promis... 如果你需要趕上我們關(guān)于Promise的進(jìn)度,可以看看這個(gè)系列前兩篇文章深入理解Promise五部曲--1.異步問(wèn)題和深入理解Promise五部曲--2.控制權(quán)轉(zhuǎn)移問(wèn)題。 Promi...

    XboxYan 評(píng)論0 收藏0
  • 深入理解async/await來(lái)處理異步

    摘要:雖然在后面,但是我先執(zhí)行繼續(xù)看控制臺(tái)原來(lái)函數(shù)返回的是一個(gè)對(duì)象,如果要獲取到返回值,我們應(yīng)該用方法,繼續(xù)修改代碼。這就是來(lái)處理異步。 目前async/await 已經(jīng)被標(biāo)準(zhǔn)化,我們需要盡快將學(xué)習(xí)進(jìn)程提上日程。先說(shuō)一下async的用法,它作為一個(gè)關(guān)鍵字放到函數(shù)前面,用于表示函數(shù)是一個(gè)異步函數(shù),因?yàn)閍sync就是異步的意思,異步函數(shù)也就意味著該函數(shù)的執(zhí)行不會(huì)阻塞后面代碼的執(zhí)行。下面寫(xiě)一個(gè)as...

    luzhuqun 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<