<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>

          實現(xiàn) Promises/A+ api屬性源碼附帶注解詳情

          共 9632字,需瀏覽 20分鐘

           ·

          2022-07-13 07:58

          簡單的 Promises/A+ 實現(xiàn)

          博客:webvueblog.github.io/promise/

          倉庫地址:promise

          MiniPromise.js 實現(xiàn)

          • MiniPromise.resolve()

          • MiniPromise.reject()

          • MiniPromise.then()

          • MiniPromise.all()

          • MiniPromise.race()

          • MiniPromise.any()

          • MiniPromise.allSettled()

          通篇講解promise,學(xué)習(xí)promise相關(guān)內(nèi)容,熟練使用promise;了解promise可以做什么,不可以做什么。

          promise是抽象異步處理對象以及對其進行各種操作的組件。promise最初被提出是在E語言中,它是基于并列/并行處理設(shè)計的一編程語言。

          我們在 基于JavaScript的異步處理,大都想到使用回調(diào)函數(shù)。

          使用回調(diào)函數(shù)的異步處理

          getAsync("file.txt", function(error, result) { // 取得失敗時的處理
          if (error) { throw error;
          } // 取得成功時的處理});復(fù)制代碼

          node.js 規(guī)定在 JavaScript 的回調(diào)函數(shù)的一個參數(shù)為 error 對象,這是 Node.js 的一般寫法。

          promsie 時可以將復(fù)雜的異步處理輕松地進行模式化,寫法:

          var promise = getAsyncPromise('file.txt');
          promise.then(function(result) { // 獲取文件內(nèi)容成功時的處理}).catch(function(error) { // 獲取文件內(nèi)容失敗時的處理});復(fù)制代碼

          ES6 Promise 標(biāo)準(zhǔn)

          Constructor

          Promise類似于 XMLHttpRequest,從構(gòu)造函數(shù) Promise 來創(chuàng)建一個新建的 promise 對象作為接口。

          要想創(chuàng)建一個 promise 對象,可以使用 new 來調(diào)用 promise 的構(gòu)造器來進行實例化。

          var promise = new Promise(function(resolve, reject) { // 異步處理
          // 處理結(jié)束后,調(diào)用 resolve 或 reject});復(fù)制代碼

          Instance Method

          通過 new 生成的 promise 對象為了設(shè)置其值在 resolve (成功)/ reject(失?。?時調(diào)用的回調(diào)函數(shù)可以使用 promise.then() 實例方法。

          promise.then(onFulfilled, onRejected)復(fù)制代碼
          • resolve(成功)時

            • onFulfilled 會被調(diào)用

          • reject(失敗)時

            • onRejected 會被調(diào)用

          onFulfilled, onRejected 兩個都是可選參數(shù)。

          promise.then 成功和失敗時都可以使用。對于異常進行處理時可以采用 promise.then(undefined, onRejected) 這種方式,只指定 reject 時的回調(diào)函數(shù)即可。不過這種情況下請使用 promise.catch(onRejected) 是更好的選擇。

          promise.catch(onRejected)復(fù)制代碼

          Static Method

          像 promise 這樣的全局對象還擁有一些靜態(tài)方法。

          包括 Promise.all() 還有 Promise.resolve() 等在內(nèi),主要都是一些對 Promise 進行操作的輔助方法。

          Promise工作流程

          promise工作流程代碼:

          function asyncFunction() { return new Promise(function (resolve, reject) {  setTimeout(function () {
          resolve('Async Hello world');
          }, 1000);
          });
          }復(fù)制代碼

          new Promise 構(gòu)造器之后,會返回一個 promise 對象

          asyncFunction().then(function(value) { console.log(value); // => 'Async Hello world'}).catch(function (error) { console.log(error);
          });復(fù)制代碼

          為promise對象設(shè)置 .then 調(diào)用返回值時的回調(diào)函數(shù)。

          asyncFunction 這個函數(shù)會返回 promise 對象,對于這個 promise 對象,我們調(diào)用它的 then 方法來設(shè)置 resolve 后的回調(diào)函數(shù), catch 方法來設(shè)置發(fā)生錯誤時的回調(diào)函數(shù)。

          該promise對象會在setTimeout之后的 1000ms 被 resolve, 這時 then 的調(diào)用函數(shù)會被調(diào)用,并輸出 'Async Hello world'。

          在這種情況下 catch 的回調(diào)函數(shù)并不會被執(zhí)行(因為promise返回了resolve),不過如果運行環(huán)境沒有提供 setTimeout 函數(shù)的話,那么就會產(chǎn)生異常,在 catch 中設(shè)置的回調(diào)函數(shù)就會被執(zhí)行。

          如果不使用catch方法,只使用then方法的話:

          只聲明 promise.then(onFulfilled, onRejected)

          asyncFunction().then(function (value) { console.log(value);
          },function (error) { console.log(error);
          });復(fù)制代碼

          Promise的狀態(tài)

          用 new Promise 實例化的 promise 對象有三種狀態(tài):

          • has-resolution: FulFilled

            • resolve(成功)時,此時調(diào)用 onFulfilled

          • has-rejection: Rejected

            • reject(失敗)時,此時調(diào)用 onRejected

          • unresolved: Pending

            • 既不是resolve也不是reject的狀態(tài)。也就是promise對象剛被創(chuàng)建后的初始化狀態(tài)等

          建議使用:Pending,F(xiàn)ulfilled,Rejected 的狀態(tài)名稱進行講述。

          pending -> value -> Fulfilled

          pending -> error -> Rejected

          狀態(tài)的改變

          promise 對象的狀態(tài),從 Pending 轉(zhuǎn)換為 Fulfilled 或 Rejected 之后,這個 promise 對象的狀態(tài)就不會再發(fā)生任何變化。

          在 .then 后執(zhí)行的函數(shù)可以肯定地說只會被調(diào)用一次。并且 Fulfilled 和 Rejected 這兩個中的任一狀態(tài)都可以表示為 Settled(不變的)。

          Settled

          resolve(成功) 或 reject(失敗)

          當(dāng) promise 的對象狀態(tài)發(fā)生變化時,用 .then 來定義只會被調(diào)用一次的函數(shù)。

          Promise 代碼

          創(chuàng)建promise對象的流程:

          1. new Promise(fn) 返回一個 promise 對象

          2. 在 fn 中指定異步等處理

            • 處理結(jié)果正常的話,調(diào)用 resolve(處理結(jié)果值)

            • 處理結(jié)果錯誤的話,調(diào)用 reject(Error對象)

          用 Promise 來通過異步處理方式來獲取 XMLHttpRequest(XHR)的數(shù)據(jù):

          來創(chuàng)建XHR的promise對象

          // 運行示例var URL = "http://xxx.org/get";
          getURL(URL).then(function onFulfilled(value){console.log(value);
          }).catch(function onRejected(error){console.error(error);
          });function getURL(URL) { return new Promise(function (resolve, reject) { var req = new XMLHttpRequest();
          req.open('GET', URL, true);
          req.onload = function () { if (req.status === 200) {
          resolve(req.responseText);
          } else {
          reject(new Error(req.statusText));
          }
          };
          req.onerror = function () {
          reject(new Error(req.statusText));
          };
          req.send();
          });
          }復(fù)制代碼

          為promise對象添加處理方法主要有以下兩種

          • promise對象被 resolve 時的處理(onFulfilled)

          • promise對象被 reject 時的處理(onRejected)

          此時所謂的 通信成功 , 指的就是在被resolve后, promise對象變?yōu)镕ulFilled狀態(tài) 。

          被resolve后的處理,可以在 .then 方法中傳入想要調(diào)用的函數(shù)。

          用 new Promise 方法創(chuàng)建promise對象

          用 .then 或 .catch 添加promise對象的處理函數(shù)

          Promise.resolve

          靜態(tài)方法 Promise.resolve(value) 可以認(rèn)為是 new Promise() 方法的快捷方式。

          Promise.resolve(18); 等同于 可以認(rèn)為是以下代碼的語法糖:

          new Promise(function(resolve){
          resolve(18);
          });復(fù)制代碼

          方法 Promise.resolve(value); 的返回值也是一個promise對象

          Promise.resolve(18).then(function(value){    console.log(value);
          })復(fù)制代碼

          Promise.resolve 方法另一個作用就是將 thenable 對象轉(zhuǎn)換為promise對象。

          Promise.resolve 方法另一個作用就是將 thenable 對象轉(zhuǎn)換為promise對象。

          ES6 Promises里提到了Thenable這個概念,簡單來說它就是一個非常類似promise的東西。

          就像我們有時稱具有 .length 方法的非數(shù)組對象為Array like一樣,thenable指的是一個具有 .then 方法的對象。

          這種將thenable對象轉(zhuǎn)換為promise對象的機制要求thenable對象所擁有的 then 方法應(yīng)該和Promise所擁有的 then 方法具有同樣的功能和處理過程,在將thenable對象轉(zhuǎn)換為promise對象的時候,還會巧妙的利用thenable對象原來具有的 then 方法。

          到底什么樣的對象能算是thenable的呢,最簡單的例子就是 jQuery.ajax(),它的返回值就是thenable的。

          $.ajax('/json/comment.json');// => 擁有 `.then` 方法的對象復(fù)制代碼

          這個thenable的對象可以使用 Promise.resolve 來轉(zhuǎn)換為一個promise對象。

          將thenable對象轉(zhuǎn)換promise對象

          var promise = Promise.resolve($.ajax('/json/comment.json'));// => promise對象promise.then(function(value){    console.log(value);
          });復(fù)制代碼

          Promise.resolve 方法可以認(rèn)為它的作用就是將傳遞給它的參數(shù)填充(Fulfilled)到promise對象后并返回這個promise對象。

          Promise.reject

          Promise.reject(error) 是 new Promise() 方法的快捷方式。

          比如 Promise.reject(new Error("出錯了")) 就是下面代碼的語法糖形式。

          new Promise(function(resolve,reject){
          reject(new Error("出錯了"));
          });復(fù)制代碼

          這段代碼的功能是調(diào)用該promise對象通過then指定的 onRejected 函數(shù),并將錯誤(Error)對象傳遞給這個 onRejected 函數(shù)。

          Promise.reject(new Error("BOOM!")).catch(function(error){    console.error(error);
          });復(fù)制代碼

          .then 中指定的方法調(diào)用是異步進行的

          var promise = new Promise(function (resolve){    console.log("inner promise"); // 1
          resolve(18);
          });

          promise.then(function(value){ console.log(value); // 3});console.log("outer promise"); // 2復(fù)制代碼
          function onReady(fn) { var readyState = document.readyState; if (readyState === 'interactive' || readySate === 'complete') {
          fn();
          } else { window.addEventListener('DOMContentLoaded', fn);
          }
          }

          onReady(function () { console.log('DOM fully loaded and parsed');
          });復(fù)制代碼

          then

          promise可以寫成方法鏈的形式

          aPromise.then(function taskA(value){    // task A}).then(function taskB(vaue){    // task B}).catch(function onRejected(error){    console.log(error);
          });復(fù)制代碼

          promise chain

          promise-then-catch-flow.js

          function taskA() {    console.log("Task A");
          }function taskB() { console.log("Task B");
          }function onRejected(error) { console.log("Catch Error: A or B", error);
          }function finalTask() { console.log("Final Task");
          }var promise = Promise.resolve();

          promise
          .then(taskA)
          .then(taskB)
          .catch(onRejected)
          .then(finalTask);復(fù)制代碼

          • then

            • 注冊 onFulfilled 時的回調(diào)函數(shù)

          • catch

            • 注冊 onRejected 時的回調(diào)函數(shù)

          promise chain 中如何傳遞參數(shù)

          return 返回值

          每個方法中 return 的值不僅只局限于字符串或者數(shù)值類型,也可以是對象或者promise對象等復(fù)雜類型

          return的值會由 Promise.resolve(return的返回值); 進行相應(yīng)的包裝處理,因此不管回調(diào)函數(shù)中會返回一個什么樣的值,最終 then 的結(jié)果都是返回一個新創(chuàng)建的promise對象

          Promise.then 不僅僅是注冊一個回調(diào)函數(shù)那么簡單,它還會將回調(diào)函數(shù)的返回值進行轉(zhuǎn)換,創(chuàng)建并返回一個 promise 對象。

          catch

          Promise.cath 只是 promise.then(undefined, onRejected); 方法的一個別名而已。這個方法用來注冊當(dāng)promise對象狀態(tài)變?yōu)镽ejected時的回調(diào)函數(shù)。

          var promise = Promise.reject(new Error("message"));
          promise.catch(function (error) { console.error(error);
          });復(fù)制代碼

          解決Promise.catch標(biāo)識符沖突問題

          var promise = Promise.reject(new Error("message"));
          promise["catch"](function (error) { console.error(error);
          });var promise = Promise.reject(new Error("message"));
          promise.then(undefined, function (error) { console.error(error);
          });復(fù)制代碼

          每次調(diào)用then都會返回一個新創(chuàng)建的promise對象

          不管是 then 還是 catch 方法調(diào)用,都返回了一個新的promise對象。

          var aPromise = new Promise(function (resolve) {
          resolve(100);
          });var thenPromise = aPromise.then(function (value) { console.log(value);
          });var catchPromise = thenPromise.catch(function (error) { console.error(error);
          });console.log(aPromise !== thenPromise); // => trueconsole.log(thenPromise !== catchPromise);// => true復(fù)制代碼

          then 和 catch 都返回了和調(diào)用者不同的promise對象。

          promise object -> then(promise object)(value -> onFulfilled; error -> onRejected) -> catch(error -> onRejected)

          then 的使用方式上的差別

          Promise.all

          Promise.all 接收一個 promise對象的數(shù)組作為參數(shù),當(dāng)這個數(shù)組里的所有promise對象全部變?yōu)閞esolve或reject狀態(tài)的時候,它才會去調(diào)用 .then 方法。

          使用一個計時器來計算一下程序執(zhí)行時間

          // `delay`毫秒后執(zhí)行resolvefunction timerPromisefy(delay) {    return new Promise(function (resolve) {        setTimeout(function () {
          resolve(delay);
          }, delay);
          });
          }var startDate = Date.now();// 所有promise變?yōu)閞esolve后程序退出Promise.all([
          timerPromisefy(1),
          timerPromisefy(32),
          timerPromisefy(64),
          timerPromisefy(128)
          ]).then(function (values) { console.log(Date.now() - startDate + 'ms'); // 約128ms
          console.log(values); // [1,32,64,128]});復(fù)制代碼

          Promise.race

          Promise.race 方法 ,接收一個promise對象數(shù)組為參數(shù)。

          Promise.all 在接收到的所有的對象promise都變?yōu)?FulFilled 或者 Rejected 狀態(tài)之后才會繼續(xù)進行后面的處理, 與之相對的是 Promise.race 只要有一個promise對象進入FulFilled 或者 Rejected 狀態(tài)的話,就會繼續(xù)進行后面的處理。

          then 與 catch 比較

          1. 使用 promise.then(onFulfilled, onRejected) 的話

            • 在 onFulfilled 中發(fā)生異常的話,在 onRejected 中是捕獲不到這個異常的。

          2. 在 promise.then(onFulfilled).catch(onRejected) 的情況下

            • then 中產(chǎn)生的異常能在 .catch 中捕獲

          3. .then 和 .catch 在本質(zhì)上是沒有區(qū)別的

            • 需要分場合使用。

          由于 .catch 方法是 .then 的別名,我們使用 .then 也能完成同樣的工作。只不過使用 .catch 的話意圖更明確,更容易理解

          練習(xí)

          then

          • promise.then(onFulfilled, onRejected);

          catch

          • promise.catch(onRejected);

          resolve

          Promise.resolve(promise);

          Promise.resolve(thenable);

          Promise.resolve(object);

          • 接收到promise對象參數(shù)的時候

            • 返回的還是接收到的promise對象

          • 接收到thenable類型的對象的時候

            • 返回一個新的promise對象,這個對象具有一個 then 方法

          • 接收的參數(shù)為其他類型的時候(包括JavaScript對或null等)

            • 返回一個將該對象作為值的新promise對象

          reject

          • Promise.reject(object)

          和 Promise.resolve不同的是,即使Promise.reject接收到的參數(shù)是一個promise對象,該函數(shù)也還是會返回一個全新的promise對象。

          all

          • Promise.all(promiseArray);

          生成并返回一個新的promise對象。

          參數(shù)傳遞promise數(shù)組中所有的promise對象都變?yōu)閞esolve的時候,該方法才會返回, 新創(chuàng)建的promise則會使用這些promise的值。

          如果參數(shù)中的任何一個promise為reject的話,則整個Promise.all調(diào)用會立即終止,并返回一個reject的新的promise對象。

          由于參數(shù)數(shù)組中的每個元素都是由 Promise.resolve 包裝(wrap)的,所以Paomise.all可以處理不同類型的promose對象。

          race

          • Promise.race(promiseArray)

          生成并返回一個新的promise對象。

          參數(shù) promise 數(shù)組中的任何一個promise對象如果變?yōu)閞esolve或者reject的話, 該函數(shù)就會返回,并使用這個promise對象的值進行resolve或者reject。

          瀏覽 36
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  91日逼视频| 亚洲在线看 | 三级草逼免费看 | 日本免费黄色小视频 | 丁香花 在线视频 婷婷综合 |