ES6 Promise的resolved深刻理解

Promise的概念在ES6標準推出來以前已經深刻人心,不少框架和第三方庫都有相似的實現。但在深刻理解ES6的Promise對象的時候,受以前經驗的影響,不少概念給人似是而非的感受,其中有一個特別明顯的地方就是ES6中對Promise對象狀態的定義以及resolved概念。

html

Promise的狀態

Promise對象有三個狀態:pending,fulfilled,rejected,MDN文檔上對Promise對象狀態變化過程用一幅圖描述:前端

圖中有幾個小細節:git

  1. 圖中的fulfill和reject只是表示指向不一樣結果,而不是指一個過程,在到達fulfilledrejected狀態前promise都處在pending狀態。
  2. settled包括了fulfilledrejected
  3. promise只會在pendingfulfilledrejected三種狀態下切換。

resolved 和 unresolved

事情在如今看來都很美好,狀態清晰,一目瞭然。然而,在各類教程中咱們會看到這樣一個狀態:resolved,阮老師的ECMAScript 6 入門中直接把它看成了fulfilled狀態:es6

Promise對象表明一個異步操做,有三種狀態:Pending(進行中)、Resolved(已完成,又稱 Fulfilled)和Rejected(已失敗)。github

可是MDN中的備註是這樣寫的:promise

你可能也會聽到一個術語resolved,它表示Promise對象處於settled狀態,或者Promise對象被鎖定在了調用鏈中。app

嗯?記不記得上面提到settled狀態包括fulfilledrejected狀態,那麼他至少不能和fulfilled狀態劃等號吧?因而我又搜了搜,發現網上不少文章提到resolved這個詞時,有人直接看成fulfilled狀態,有人把它理解爲complete(相似地,fulfilled是success,rejected天然就是error或者failure),不過更多人都是很含糊地引用了一下文檔或者阮老師的文章。框架

不過確實有人直接提出了這個問題:Promise的fulfill和resolve爲啥要用兩個詞?,我着重看了賀師俊老師的回答:dom

由於 fulfill 和 resolve 是不一樣的。
resolve 只是表示這個 promise 已經肯定了,好比 promise A 被 resolve 爲 promise B,則 A 已經 resolved 可是並未 fulfilled 。異步

好吧,我認可我一開始看沒看懂...
不過還好在備註那裏MDN放出了一篇幫助理解的文章,Domenic Denicola 的 States and Fates,基本把這兩個概念說清楚了,不過文中只有簡單的文字描述,下面說一下我本身的理解。

state 和 fates

文章將Promise分得更細,分爲了狀態(state)和結果(fates,命運,原諒我粗淺的翻譯)。

狀態(state)就是上面提到的三種狀態,須要稍微留意一下的是,文中提到settled不是一種Promise狀態,只是一種語義上的便利,說白了就是描述Promise肯定了而已。

結果(fates)分爲resolvedunresolved,兩種結果互斥。

  • resolved,原文解釋有點繞:

    A promise is resolved if trying to resolve or reject it has no effect,當沒辦法去resolve或reject一個promise的時候,這個promise就是resolved的。

  • unresolved,原文解釋卻是很簡單:非resolved的promise...... (:з」∠)

顯而易見,只要理解了resolved的描述,天然就理解unresolved。首先先提一個Promise的概念,即當Promise的狀態一旦改變,就永久保持該狀態。因此何時沒辦法去resolve或reject一個promise對象呢?

  1. 處於fulfilledrejected狀態的promise對象,由於他們已經沒法改變狀態,而resolve和reject只能對pending狀態的promise有效。
  2. 處於pending狀態的promise對象也有可能處於resolved,當promise對象被'鎖定'在另一個promise對象或者一個非即時返回的thenable函數中時,也就是上面賀老師提到的promise A 被 resolve 爲 promise B這種狀況,爲了幫助理解,下面用代碼舉個例子。

說明:Chrome(57.0.2987.133)打印promise對象的時候,[[PromiseStatus]]有三個值:pending,resolved,rejected,這裏的resolved狀態就是指fulfilled狀態,和咱們要說明的resolved沒有關係,在firefox(49.0.1)中,[[PromiseStatus]]三個值和標準相同:pending,fulfilled,rejected。爲了不混淆,用firefox作測試

先上一個簡單的代碼:

var p1 = new Promise((resolve, reject) => {
    setTimeout(resolve, 1000, 'p1 resolve');
});
p1.then(value => {
    console.log(value);   // p1 resolve
    console.log(p1);   //  Promise { <state>: "fulfilled", <value>: "p1 resolve" }
})

很簡單,一秒後打印p1 resolve,p1對象狀態爲fulfilled。再來看第二例子,在resolve方法中新建了一個Promise對象:

var p1 = new Promise((resolve, reject) => {
    function F() {
        resolve(new Promise((resolve, reject) => {
            console.log(p1);  //  Promise { <state>: "pending" }
            setTimeout(resolve, 2000, 'new Promise resolve');
        }))
    }
    setTimeout(F, 1000, 'p1 resolve');
});
p1.then(function(value) {
    console.log(value);  //  new Promise resolve
    console.log(p1);  //  Promise { <state>: "fulfilled", <value>: "new Promise resolve" }
})

運行一下發現,一秒後打印

Promise { <state>: "pending" }

三秒後打印

new Promise resolve
Promise { <state>: "fulfilled", <value>: "new Promise resolve" }

能夠看到,一秒後p1調用了resolve方法,和上一個例子同樣被resolve了,理應變爲fulfilled狀態,可是他被'鎖定'在了一個新的Promise對象中,因此狀態沒有馬上改變並執行onfulfilled方法,而是依然處於pending狀態,可是很明顯的是,他的最終結果(這裏能夠體會到稱爲fate的緣由,有種宿命的味道)就是fulfilled狀態,此時的p1不能再resolve或reject。再過了兩秒後新Promise對象resolve,p1執行then(),狀態變爲fulfilled,打印的值也變成了new Promise resolve,而不是p1 resolve。此時打印出的p1的狀態就是fulfilled。

到此,處於pending狀態的promise對象也有可能處於resolved狀況就很清楚了,至於unresolved,就是promise能夠被resolve或reject的時候,此時promise對象必定處於pending狀態且沒有被resolve或reject爲其餘Promise對象 / 非即時返回的thenable函數。而反過來,處於pending狀態的promise對象不必定是unresolved。

小結

到這裏Promise對象的狀態和resolved的概念差很少都清楚了,這篇文章也是我我的理解過程的一個記錄。不過參考到的文章很少,文中的解釋可能並非很準確,因此在這裏貼出來,但願能看看其餘人的理解。


一些閒話

提及來,這篇文章離我上一篇文章已經好久了,真是光陰似箭,歲月......算了,仍是不感慨了。如今工做確實沒有在學校那會兒充足的時間和精力,總結仍是有很多,大部分都在我的的筆記裏,沒有貼到博客。有些以爲總結分量不夠,有些以爲我的的理解不深,不敢隨意貼出來。不過在學習一些稍微深刻一點的概念的時候,總以爲網上的一些資料並非很全面和客觀,人云亦云的東西太多,本身的理解也是七七八八。因此但願可以貼出來和你們交流,防止本身閉門造車,後續若是工做時間容許,會發一些這樣的文章,對前端一些比較重要的知識點深刻理解。




本文來源:JuFoFu

本文地址:http://www.cnblogs.com/JuFoFu/p/5140302.html




參考文檔:

Domenic Denicola . States and Fates

阮一峯 . Promise 對象

MDN . Promise

水平有限,錯誤歡迎指正。原創博文,轉載請註明出處。
相關文章
相關標籤/搜索