国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Promise——從閱讀文檔到簡單實現(一)

yanwei / 1830人閱讀

摘要:意味著操作成功完成。方法接收失敗情況的回調函數作為參數,返回一個對象。參數回調函數不接收任何參數,當對象變成狀態時被調用。現在各個方法的參數返回值功能和使用方法已經有個大概的了解了,為了進一步理解其原理,接下來我打算簡單地實現一下它。

前言

最近幾周參加筆試面試,總是會遇到實現異步和處理異步的問題,然而作者每次都無法完美地回答。在最近一次筆試因為 Promise 而被刷掉后,我終于下定決心一個個地搞懂它們,就先拿 Promise 開刀吧 :)。

用法解析

ES6 的Promise對象是一個代理對象,被代理的值在Promise對象創建時可能是未知的,另外它允許你為異步操作的成功和失敗分別綁定相應的處理方法。
Promise 常用于控制異步操作的執行順序,而且可以讓異步方法像同步方法那樣返回值。它不能立即取得異步方法的返回值,但是它可以代理這個值,一旦異步操作完成,就會以及將值傳遞給相應的處理方法。
一個Promise對象有以下幾種狀態:

pending: 初始狀態,既不是成功,也不是失敗狀態。

fulfilled: 意味著操作成功完成。

rejected: 意味著操作失敗。

一個Promise對象的狀態可以從pending變成fulfilled,同時傳遞一個值給相應的onfulfilled處理方法;也可以從pending變成rejected,同時傳遞一個失敗信息給相應的onrejected處理方法。
一旦一個Promise對象的狀態發生改變,就會觸發之前通過Promise.prototype.then、 Promise.prototype.catch和 Promise.prototype.finally方法綁定的onfulfilledonrejectedonFinally處理方法。
因為 thencatchfinally方法都會返回一個新的Promise對象, 所以它們可以被鏈式調用。

構造函數

構造函數Promise()主要用來包裝還未支持 promises 的函數。

new Promise( function(resolve, reject) {...} /* executor */  );

參數:executor
executor是帶有 resolvereject 兩個函數參數的函數。Promise構造函數執行時立即調用executor函數,換句話說,executor函數是在Promise構造函數內執行的,所以它是同步代碼。在executor函數內調用 resolvereject 函數,可以傳遞參數給相應的處理方法,并會分別將 promise 新建對象的狀態改為fulfilled(完成)或rejected(失敗)。
executor 內部通常會執行一些異步操作如ajax,一旦完成,可以調用resolve函數傳遞參數并將 promise 對象的狀態改成 fulfilled,或者在發生錯誤時調用reject 函數傳遞參數并將 promise 對象的狀態改成 rejected。如下:

function myAsyncFunction(url) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open("GET", url);
    xhr.onload = () => resolve(xhr.responseText);
    xhr.onerror = () => reject(xhr.statusText);
    xhr.send();
  });
};

如果在executor函數中拋出一個錯誤,那么該 promise 對象狀態將變為rejected,并將錯誤作為參數傳遞給對應的onrejected處理方法。如下:

function myAsyncFunction(url) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open("GET", url);
    xhr.onerror = () => {
        throw xhr.statusText;
        //throw xhr.statusText 效果等同于 reject(xhr.statusText)
    };
    xhr.send();
  });
};
靜態方法

靜態方法是定義在構造函數上的方法,聲明靜態方法:

Func.fn = function() {}

調用靜態方法:

Func.fn(args);

ES6中的Promise構造函數有4個靜態方法:

Promise.resolve(value)

Promise.reject(reason)

Promise.all(iterable)

Promise.race(iterable)

Promise.resolve(value):
返回一個由參數value解析而來的Promise對象。

如果傳入的value本身就是Promise對象,則直接返回value

如果value是一個thenable對象(帶有 then 方法的對象),返回的Promise對象會跟隨這個thenable對象,狀態隨之變化;

其它情況下返回的Promise對象狀態為fulfilled,并且將該value作為參數傳遞給onfulfilled處理方法。

通常而言,如果你不知道一個值是否為Promise對象,就可以使用 Promise.resolve(value) 來將valuePromise對象的形式使用。

    // resolve一個thenable對象
    var p1 = Promise.resolve({ 
      then: function(onFulfill, onReject) { onFulfill("fulfilled!"); }
    });
    console.log(p1 instanceof Promise) // true, 這是一個Promise對象
    
    p1.then(function(v) {
        console.log(v); // 輸出"fulfilled!"
      }, function(e) {
        // 不會被調用
    });

Promise.reject(reason):
返回一個被給定原因reason拒絕的Promise對象。
返回的Promise對象的status狀態屬性為rejectedreason拒絕原因屬性(傳遞給onrejected處理方法的 reason 參數)與參數reason相等。

Promise.reject(new Promise((resolve, reject) => resolve("done")))
.then(function(reason) {
      // 未被調用
}, function(reason) {
      console.log(reason); // new Promise
});

Promise.all(iterable):
參數:iterable對象為Array對象、Map對象和Set對象等可迭代對象。
返回:一個Promise對象。

如果iterable不是一個可迭代對象,Promise.all會同步地返回返回一個狀態為rejected ,拒絕原因reson為類型錯誤的 promise 對象;

如果iterable對象為空,Promise.all會同步地返回一個狀態為fulfilledvalue值為空數組的 promise 對象;

如果iterable對象中的 promise 對象都變為fulfilled狀態,或者iterable對象內沒有 promise 對象,Promise.all返回的 promise 對象將異步地變為fulfilled狀態。這兩種情況返回的 promise 對象的value值(傳遞給onfulfilled處理方法的 value 參數)都是一個數組,這個數組包含iterable對象中所有的基本值和 promise 對象value值,這些值將會按照參數iterable內的順序排列,而不是由 promise 的完成順序決定;

如果iterable對象中任意一個 promise 對象狀態變為rejected,那么Promise.all就會異步地返回一個狀態為rejected的 promise 對象,而且此 promise 對象的reason值(傳遞給onrejected處理方法的 reason 參數),等于iterable對象中狀態為rejected的那一個 promise 對象的reason值。

    // this will be counted as if the iterable passed is empty, so it gets fulfilled
    var p = Promise.all([1,2,3]);
    // this will be counted as if the iterable passed contains only the resolved promise with value "333", so it gets fulfilled
    var p2 = Promise.all([1,2,3, Promise.resolve(333)]);
    // this will be counted as if the iterable passed contains the rejected promise with value "444", so it gets rejected
    var p3 = Promise.all([1,2, Promise.reject(444), Promise.reject(555)]);
    
    // using setTimeout we can execute code after the stack is empty
    setTimeout(function(){
        console.log(p);
        console.log(p2);
        console.log(p3);
    });
    
    // logs
    // Promise { : "fulfilled", : Array[3] }
    // Promise { : "fulfilled", : Array[4] }
    // Promise { : "rejected", : 444 }

Promise.race(iterable):
返回一個Promise對象。

如果iterable不是一個可迭代對象,Promise.race會同步地返回返回一個狀態為rejected,拒絕原因reson為類型錯誤的 promise 對象;

如果iterable對象為空,Promise.all會同步地返回一個狀態為fulfilledvalue值為空數組的 promise 對象;

如果iterable對象不為空,一旦iterable中的某個 promise 對象完成或拒絕,返回的 promise 對象就會完成或拒絕,且返回的 promise 對象的value值(完成時)或reason值(拒絕時)和這個 promise 對象的value值(完成時)或reason值(拒絕時)相等。

    var promise1 = new Promise(function(resolve, reject) {
        setTimeout(resolve, 500, "one");
    }), promise2 = new Promise(function(resolve, reject) {
        setTimeout(resolve, 100, "two");
    });
    
    Promise.race([promise1, promise2]).then(function(value) {
      console.log(value);
      // Both resolve, but promise2 is faster
    });
    // expected output: "two"
實例方法

實例方法是定義在原型對象上的方法,聲明實例方法:

Func.prototype.fn = function() {}

調用實例方法需要先創建一個實例:

let func = new Func();
func.fn(args);

Promise的原型對象上有3個實例方法:

Promise.prototype.then(onFulfilled, onRejected)

Promise.prototype.catch(onRejected)

Promise.prototype.finally(onFinally)

Promise.prototype.then(onFulfilled, onRejected):
then方法接收成功和失敗兩種情況的回調函數作為參數,返回一個Promise對象。

參數:onFulfilledonRejected回調函數。
onFulfilled:當 promise 對象變成 fulfilled 狀態時被調用。onFulfilled函數有一個參數,即 promise 對象完成時的 value 值。如果onFulfilled不是函數,它會在then方法內部被替換成一個Identity函數,即 (x) => (x) 。
onRejected:當 promise 對象變成 rejected 狀態時被調用。onRejected函數有一個參數,即 promise 對象失敗時的 reason 值。如果onRejected不是函數,它會在then方法內部被替換成一個Thrower函數,即 (reason) => {throw reason} 。

返回:一旦調用then方法的 promise 對象被完成或拒絕,將異步調用相應的處理函數(onFulfilledonRejected),即將處理函數加入microtask隊列中。如果onFulfilledonRejected回調函數:

返回一個值,則then返回的 promise 對象的status變為fulfilledvalue變為回調函數的返回值;

不返回任何內容,則then返回的 promise 對象的status變為fulfilledvalue變為undefined

拋出一個錯誤,則then返回的 promise 對象的status變為rejectedreason變為回調函數拋出的錯誤;

返回一個狀態為fulfilled的 promise 對象,則then返回的 promise 對象的status變為fulfilledvalue等于回調函數返回的 promise 對象的value值;

返回一個狀態為rejected的 promise 對象,則then返回的 promise 對象的status變為rejectedreason等于回調函數返回的 promise 對象的reason值;

返回一個狀態為pending的 promise 對象,則then返回的 promise 對象的status變為pending,且其status將隨著回調函數返回的 promise 對象的status變化而變化,之后其valuereason值也會和此 promise 對象的valuereason值相同。

這里提一下,這個地方看 MDN 文檔中文翻譯實在看不懂,之后看英文原文反而稍微理解了,希望之后在實現 Promise 的過程中能理解更深。

    var fromCallback;
    
    var fromThen = Promise.resolve("done")
    .then(function() {
        fromCallback = new Promise(function(){});
        return fromCallback;
    });
    
    setTimeout(function() {
        console.log(fromCallback);    //fromCallback.status === "pending"
        console.log(fromThen);        //fromThen.status === "pending"
        console.log(fromCallback === fromThen);    //false
    }, 0);

Promise.prototype.catch(onRejected):
catch方法接收失敗情況的回調函數作為參數,返回一個Promise對象。
參數:onRejected回調函數,表現同then中的onRejected參數。
返回:promiseObj.catch(onRejected) 與 promiseObj.then(undefined, onRejected) 返回值相同。

    Promise.resolve()
      .then( () => {
        // 返回一個 rejected promise
        throw "Oh no!";
      })
      .catch( reason => {
        console.error( "onRejected function called: ", reason );
      })
      .then( () => {
        console.log( "I am always called even if the prior then"s promise rejects" );
      });

Promise.prototype.finally(onFinally):
finally方法接收onFinally回調函數作為參數,返回一個Promise對象。
如果你想在 promise 執行完畢后,無論其結果是成功還是失敗,都做一些相同的處理時,可以使用finally方法。
參數:onFinally回調函數
onFinally不接收任何參數,當 promise 對象變成 settled (fulfilled / rejected) 狀態時onFinally被調用。
返回:如果onFinally回調函數

不返回任何內容或者返回一個值或者返回一個狀態為fulfilled的 promise 對象,則finally返回的 promise 對象的statusvaluereason值與調用這個finally方法的 promise 對象的值相同;

拋出一個錯誤或者返回一個狀態為rejected的 promise 對象,則finally返回的 promise 對象的status值變為rejectedreason值變為被拋出的錯誤或者回調函數返回的 promise 對象的reason值;

返回一個狀態為pending的 promise 對象,則finally返回的 promise 對象的status值變為pending,且其status值將隨著回調函數返回的 promise 對象的status值變化而變化,之后其valuereason值也會和此 promise 對象的valuereason值相同。

Promise.reject("是我,開心嗎").finally(function() {
    var pro = new Promise(function(r){r("你得不到我")});    //pro.status === "fulfilled"
    return pro;    //`onFinally`回調函數返回一個狀態為`fulfilled`的 promise 對象
}).catch(function(reason) {
    console.log(reason);
});
結語

將 MDN 文檔整理了一下,加入了一些自己的理解,也花費了一天的時間。現在Promise各個方法的參數、返回值、功能和使用方法已經有個大概的了解了,為了進一步理解其原理,接下來我打算簡單地實現一下它。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/102577.html

相關文章

  • Promise——閱讀文檔簡單實現(二)

    摘要:在和方法執行的時候訂閱事件,將自己的回調函數綁定到事件上,屬性是發布者,一旦它的值發生改變就發布事件,執行回調函數。實現和方法的回調函數都是,當滿足條件對象狀態改變時,這些回調會被放入隊列。所以我需要在某個變為時,刪除它們綁定的回調函數。 前言 按照文檔說明簡單地實現 ES6 Promise的各個方法并不難,但是Promise的一些特殊需求實現起來并不簡單,我首先提出一些不好實現或者容...

    dinfer 評論0 收藏0
  • ES6-7

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

    mudiyouyou 評論0 收藏0
  • 理解 Javascript 中的 Promise

    摘要:理解承諾有兩個部分。如果異步操作成功,則通過的創建者調用函數返回預期結果,同樣,如果出現意外錯誤,則通過調用函數傳遞錯誤具體信息。這將與理解對象密切相關。這個函數將創建一個,該將在到秒之間的隨機數秒后執行或。 想閱讀更多優質文章請猛戳GitHub博客,一年百來篇優質文章等著你! showImg(https://segmentfault.com/img/bVbkNvF?w=1280&h=...

    paulli3 評論0 收藏0
  • 理解 Javascript 中的 Promise

    摘要:理解承諾有兩個部分。如果異步操作成功,則通過的創建者調用函數返回預期結果,同樣,如果出現意外錯誤,則通過調用函數傳遞錯誤具體信息。這將與理解對象密切相關。這個函數將創建一個,該將在到秒之間的隨機數秒后執行或。 想閱讀更多優質文章請猛戳GitHub博客,一年百來篇優質文章等著你! showImg(https://segmentfault.com/img/bVbkNvF?w=1280&h=...

    chaos_G 評論0 收藏0
  • Node程序debug小記

    摘要:當前的部分代碼狀態超時再縮小了范圍以后,進一步進行排查。函數是一個很簡單的一次性函數,在第一次被觸發時調用函數。因為上述使用的是,而非,所以在獲取的時候,肯定為空,那么這就意味著會繼續調用函數。 有時候,所見并不是所得,有些包,你需要去翻他的源碼才知道為什么會這樣。 背景 今天調試一個程序,用到了一個很久之前的NPM包,名為formstream,用來將form表單數據轉換為流的形式進行...

    Achilles 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<