JavaScript Promise 對(duì)象個(gè)人理解的難點(diǎn)(新手向)

ES6 Promise 的這部分,起初我看《 JavaScript 高級(jí)程序設(shè)計(jì) 》4th 的時(shí)候看得云里霧里,說(shuō)實(shí)話我不知道是不是因?yàn)樵摃?shū)第 4 版中文版的質(zhì)量有所下降,講得沒(méi)那么清晰透徹了。后來(lái)我找到阮一峰老師的《 ES6 標(biāo)準(zhǔn)入門(mén)》重看了這部分,《 ES6 標(biāo)準(zhǔn)入門(mén) 》中的 Promise 這部分很合我的胃口,其中舉的例子是真的好。PS:但《 ES6 標(biāo)準(zhǔn)入門(mén) 》我也認(rèn)為有個(gè)小缺點(diǎn)——重點(diǎn)知識(shí)沒(méi)有加粗(或者其他標(biāo)記或者標(biāo)記的重點(diǎn)較少),你必須仔細(xì)的看每一句話,不然你可能錯(cuò)過(guò)一個(gè)很重要的知識(shí),或許該書(shū)是全程干貨?
雖然我說(shuō)是新手向,但我不想廢話,所以本文還是假設(shè)你在其他地方看過(guò) Promise 的內(nèi)容,只是感覺(jué)沒(méi)理解。或者其實(shí)這篇博客我只是想總結(jié)給我自己看?


構(gòu)造函數(shù)


  1. Promise 構(gòu)造函數(shù)接受一個(gè)執(zhí)行器(executor)函數(shù)作為參數(shù)。這個(gè)參數(shù)是必選的。

      let p = new Promise(() => {});
    

    這里給了一個(gè)空函數(shù)作為執(zhí)行器函數(shù)也是可以的。

  2. 這個(gè)執(zhí)行器函數(shù)什么時(shí)候開(kāi)始執(zhí)行呢?它是異步執(zhí)行的嗎?

    let p = new Promise((resolve,reject) => {
      console.log('1: 這里是執(zhí)行器函數(shù)啦');
    });
    console.log('2: Promise 實(shí)例化之后');
    console.log('3:', p);
    
    // 輸出
    // 1: 這里是執(zhí)行器函數(shù)啦
    // 2: Promise 實(shí)例化之后
    // 3: Promise { <pending> }
    

    所以我的結(jié)論是:執(zhí)行器函數(shù)在實(shí)例化 Promise 時(shí)會(huì)被同步調(diào)用
    我沒(méi)看源碼哈,我猜 Promise 構(gòu)造函數(shù)大概長(zhǎng)這樣:

    function Promise(executor) {
      ...// 略去一萬(wàn)行~
      executor(resolve, reject);
      ...// 略
    }
    

    等我看了源碼回來(lái)填坑。

  3. 執(zhí)行器函數(shù)的參數(shù) resolve 和 reject。這兩個(gè)參數(shù)很重要,關(guān)系到 Promise 的機(jī)制。

    • Promise 實(shí)例有三種可能的狀態(tài):pending(待定)、fulfilled(兌現(xiàn),有時(shí)候也稱為“解決”,resolved)、rejected(拒絕)。注意:瀏覽器控制臺(tái)才能打印出 Promise 實(shí)例的狀態(tài)。
    • 執(zhí)行器函數(shù)的兩個(gè)參數(shù) resolve 和 reject 是兩個(gè)函數(shù),由 JS 引擎提供,不用自己部署。你也無(wú)法自己定義 resolve 和 reject。
      function myExecutor(resolve, reject) {
        console.log('這里是執(zhí)行器,over');
      }
      
      let p = new Promise(myExecutor);
      
      // 這里是執(zhí)行器,over
      
      這樣寫(xiě)很清晰了吧,這里自己定義的 myExecutor 中的參數(shù) resolve 和 reject 都是形參(你想怎么命名都可以哦),myExecutor 調(diào)用是由 JS 引擎完成的,所以實(shí)參只能由 JS 引擎給。稍微完善一下猜測(cè)的 Promise 構(gòu)造函數(shù):
      function Promise(executor) {
        ...// 略去一萬(wàn)行~
        let resolve = function () {
          ...// 這里便是 JS 引擎定義的 resolve 函數(shù)
        }
        let reject = function () {
          ...// 這里便是 JS 引擎定義的 reject 函數(shù)
        }
        executor(resolve, reject);
        ...// 略
      }
      
    • pending(待定)是 Promise 實(shí)例的最初始狀態(tài)。在執(zhí)行器函數(shù)中調(diào)用 resolve() 會(huì)把 Promise 實(shí)例狀態(tài)切換為 fulfilled(解決),調(diào)用 reject() 會(huì)把狀態(tài)切換為 rejected(拒絕)。另外,調(diào)用 reject() 也會(huì)拋出錯(cuò)誤
      let p = new Promise((resolve,reject) => {
        console.log('1: 這里是執(zhí)行器函數(shù)啦');
        // 執(zhí)行器函數(shù)中調(diào)用 resolve 
        resolve();
      });
      console.log('2: Promise 實(shí)例化之后');
      console.log('3:', p);
      
      // 1: 這里是執(zhí)行器函數(shù)啦
      // 2: Promise 實(shí)例化之后
      // 3: Promise {<fulfilled>: undefined}
      
      let p = new Promise((resolve,reject) => {
        console.log('1: 這里是執(zhí)行器函數(shù)啦');
        // 執(zhí)行器函數(shù)中調(diào)用 reject 
        reject();
      });
      console.log('2: Promise 實(shí)例化之后');
      console.log('3:', p);
      
      // 1: 這里是執(zhí)行器函數(shù)啦
      // 2: Promise 實(shí)例化之后
      // 3: Promise {<rejected>: undefined}
      // 這里還有個(gè) error : Uncaught (in promise) undefined
      
  4. 為什么說(shuō) Promise 是目前主導(dǎo)性的異步編程機(jī)制?前面的例子中都沒(méi)有出現(xiàn)異步操作。執(zhí)行器函數(shù)是同步執(zhí)行的,那么 Promise 的異步在哪?

    • 雖然執(zhí)行器函數(shù)是同步執(zhí)行的,但是可以用執(zhí)行器函數(shù)把異步操作包裹起來(lái)。比如在執(zhí)行器函數(shù)中調(diào)用 setTimeout()。
      let p = new Promise((resolve,reject) => {
        console.log('1');
        setTimeout(console.log, 0, '2');
        console.log('3');
      });
      console.log('4', p);
      setTimeout(console.log, 0, '5', p);
      
      // 1
      // 3
      // 4 Promise { <pending> }
      // 2
      // 5 Promise { <pending> }
      
      這里有 2 和 5 兩個(gè)異步操作。

then 方法


  1. 執(zhí)行器函數(shù)中的異步操作觸發(fā) Promise 本身的異步。then 定義了 Promise 的狀態(tài)變?yōu)?fulfilled 或 rejected 時(shí)的回調(diào)函數(shù),這就是 Promise 本身的異步。執(zhí)行器函數(shù)中執(zhí)行的異步操作異步改變 Promise 實(shí)例的狀態(tài)時(shí),便觸發(fā)了 Promise 的異步。Promise 居然是微任務(wù),,,,,,我的理解要推翻重新理解了。。。。。

先寫(xiě)到這,待續(xù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容