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

水平有限,错误欢迎指正。原创博文,转载请注明出处。
相关文章
相关标签/搜索