<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          趁著過年,講講 Promise

          共 2772字,需瀏覽 6分鐘

           ·

          2021-02-11 10:13

          趁著過年,將講 Promise

          想象一下,你是一位頂級歌手,粉絲們?nèi)杖找挂苟荚跒槟慵磳l(fā)行的歌曲而發(fā)愁。

          為了緩解壓力,你答應(yīng)出版后寄給他們。你給你的粉絲一個列表。他們可以填寫自己的電子郵件地址,這樣當(dāng)歌曲可用時,所有訂閱方都能立即收到。即使出了什么大問題,比如工作室著火了,你不能發(fā)布這首歌,他們還是會得到通知。

          每個人都快樂:你,因為人們不再擠你了,還有粉絲,因為他們不會錯過這首歌。

          這是我們在編程中經(jīng)常遇到的現(xiàn)實類比:

          一個“生成代碼”,做一些事情,并需要時間。例如,通過網(wǎng)絡(luò)加載數(shù)據(jù)的一些代碼。這是一個“歌手”。

          一旦“生產(chǎn)代碼”準(zhǔn)備好了,“消費(fèi)代碼”就會想得到它的結(jié)果。許多函數(shù)可能需要這個結(jié)果。這些就是“粉絲”。

          promise是一個特殊的JavaScript對象,它將“生產(chǎn)代碼”和“消費(fèi)代碼”鏈接在一起。根據(jù)我們的類比:這是“訂閱列表”。“生成代碼”需要花費(fèi)任何時間來生成承諾的結(jié)果,而“承諾”在結(jié)果準(zhǔn)備好時使所有訂閱的代碼都可以使用該結(jié)果。

          這種類比并不十分準(zhǔn)確,因為JavaScript承諾比簡單的訂閱列表更復(fù)雜:它們有額外的特性和限制。但從一開始就很好。

          promise對象的構(gòu)造函數(shù)語法是:

          let?promise?=?new?Promise(function(resolve,?reject)?{
          ??//?executor?(the?producing?code,?"singer")
          });

          傳遞給new Promise的函數(shù)稱為executor。創(chuàng)建新承諾時,執(zhí)行程序自動運(yùn)行。它包含最終產(chǎn)生結(jié)果的生成代碼。用上面的比喻:執(zhí)行人就是“歌手”。

          它的參數(shù)resolve和reject是JavaScript本身提供的回調(diào)函數(shù)。我們的代碼只在執(zhí)行器內(nèi)部。

          當(dāng)executor獲得結(jié)果時,不管是快還是晚,都沒有關(guān)系,它應(yīng)該調(diào)用以下其中一個回調(diào)函數(shù):

          • resolve(value)—如果作業(yè)成功完成,則使用結(jié)果值。

          • reject(error)——如果發(fā)生了錯誤,error就是error對象。

          總而言之:執(zhí)行程序自動運(yùn)行并嘗試執(zhí)行一項工作。當(dāng)它完成嘗試時,如果成功就調(diào)用resolve,如果有錯誤就調(diào)用reject。

          新的promise構(gòu)造函數(shù)返回的promise對象有以下內(nèi)部屬性:

          狀態(tài)——最初是“pending”,然后在調(diào)用resolve時更改為“completed”,在調(diào)用reject時更改為“rejected”。

          result——最初未定義,然后在調(diào)用resolve(value)時更改為value,在調(diào)用reject(error)時更改為error。

          因此執(zhí)行人最終將promise移動到以下狀態(tài)之一:

          稍后我們將看到“粉絲”如何訂閱這些變化。

          下面是一個promise構(gòu)造函數(shù)和一個簡單的executor函數(shù),它的“生成代碼”需要花費(fèi)時間(通過setTimeout):

          let?promise?=?new?Promise(function(resolve,?reject)?{
          ??//?the?function?is?executed?automatically?when?the?promise?is?constructed

          ??//?after?1?second?signal?that?the?job?is?done?with?the?result?"done"
          ??setTimeout(()?=>?resolve("done"),?1000);
          });

          運(yùn)行上面的代碼,我們可以看到兩件事:

          執(zhí)行程序被自動且立即地(通過new Promise)調(diào)用。

          執(zhí)行器接收兩個參數(shù):resolve和reject。這些函數(shù)是由JavaScript引擎預(yù)先定義的,所以我們不需要創(chuàng)建它們。我們準(zhǔn)備好了就叫他們其中一個。

          在一秒鐘的“處理”之后,執(zhí)行程序調(diào)用resolve(“完成”)來生成結(jié)果。這會改變promise對象的狀態(tài):

          這是一個成功完成工作的例子,一個“fulfilled prommise”。

          下面是一個 Promise 執(zhí)行人用錯誤 reject promise 的例子:

          let?promise?=?new?Promise(function(resolve,?reject)?{
          ??//?after?1?second?signal?that?the?job?is?finished?with?an?error
          ??setTimeout(()?=>?reject(new?Error("Whoops!")),?1000);
          });

          reject(…)的調(diào)用將promise對象移動到“rejected”狀態(tài):

          總而言之,執(zhí)行者應(yīng)該執(zhí)行一項工作(通常需要花費(fèi)時間),然后調(diào)用resolve或reject來更改相應(yīng)promise對象的狀態(tài)。

          被解決或被拒絕的承諾稱為“已解決”,而不是最初的“待解決”承諾。

          執(zhí)行程序應(yīng)該只調(diào)用一個resolve或一個拒絕。任何狀態(tài)的改變都是最終的。

          所有進(jìn)一步的resolve和reject調(diào)用都被忽略:

          let?promise?=?new?Promise(function(resolve,?reject)?{
          ??resolve("done");

          ??reject(new?Error("…"));?//?ignored
          ??setTimeout(()?=>?resolve("…"));?//?ignored
          });

          其思想是執(zhí)行者完成的工作可能只有一個結(jié)果或一個錯誤。

          同樣,resolve/reject只期望一個參數(shù)(或none),并將忽略其他參數(shù)。

          萬一出了問題,遺囑執(zhí)行人應(yīng)該調(diào)用reject。這可以用任何類型的參數(shù)來完成(就像resolve)。但是建議使用Error對象(或者從Error繼承的對象)。這樣做的理由很快就會變得顯而易見。

          在實踐中,執(zhí)行程序通常異步執(zhí)行一些操作,并在一段時間后調(diào)用resolve/reject,但它并不需要這樣做。我們也可以立即調(diào)用resolve或reject,像這樣:

          let?promise?=?new?Promise(function(resolve,?reject)?{
          ??//?not?taking?our?time?to?do?the?job
          ??resolve(123);?//?immediately?give?the?result:?123
          });

          例如,這可能發(fā)生在當(dāng)我們開始做一個工作,但然后看到所有事情都已經(jīng)完成和緩存。

          這很好。我們立即有了一個解決的承諾。


          瀏覽 54
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产又爽 又黄 A片 | 欧美午夜成人视频 | 911人人妻人人澡人 | 夜夜操狠狠操 | 看毛片视频 |