【问题标题】:Does "resolve" consistently mean something distinct from "fulfill"?“解决”是否始终意味着与“实现”不同的东西?
【发布时间】:2017-06-14 00:49:18
【问题描述】:

(相关但不完全相同:JS Promises: Fulfill vs Resolve

我一直在尝试围绕 Javascript 的承诺,而我正在努力解决 resolveresolvedfulfill 的基本概念 已完成。看了几篇介绍,比如Jake Archibald's,以及浏览somerelevantspecs

States and Fates(不是官方规范,但被引用为规范作者之一编写的权威文档)中,fulfilled 是一种状态,而 resolved 是一个“命运”(无论是什么——但它们显然是不同的):

Promises 具有三种可能的互斥状态:已完成, 被拒绝,待处理。

  • 如果promise.then(f) 将调用 f ",则承诺是履行 可能。”

如果尝试 resolvereject 没有任何效果,则该 promise resolved, 即承诺已被“锁定”以跟随另一个 承诺,或已履行拒绝

特别是,resolved 包含 fulfilledrejected(以及锁定)。 reject 的“对立面”(或直接对应的函数)是 fulfill,而不是 resolveresolve 包括 reject 作为其可能性之一。

然而,spec 使用 fulfillresolve 引用 then() 方法(或其相应的抽象概念)的第一个参数:

  • 25.4:如果 p.then(f, r) 将立即将 Job 加入队列以调用函数 f,则 Promise p 实现

  • 25.4.1.1: [[Resolve]] 一个函数对象 用于解析给定的 Promise 对象的函数。

  • 25.4.1.3:将 resolve 的 [[Promise]] 内部槽设置为 promise。 将 resolve 的 [[AlreadyResolved]] 内部槽设置为 alreadyResolved。 [紧接着,reject 以完全对应的方式使用。]

  • 25.4.5.3: Promise.prototype.then ( onFulfilled , onRejected )

也许最关键的之一是

  • 25.4.4.5 承诺。解决 ( x )

MDN 描述如下:

Promise.resolve(value) 方法返回一个使用给定值解析的 Promise 对象。如果该值是 thenable(即具有“then”方法),则返回的 Promise 将“跟随”该 thenable,采用其最终状态;否则返回的承诺将履行价值。

没有提到Promise.resolve() 方法有可能拒绝。此外,还有Promise.reject() 方法,但没有Promise.fulfill() 方法。所以这里,reject的对应物是resolve,而不是fulfill

当然,“命运”术语resolved 和方法(或动词)resolve 之间可能没有保证的相关性。但是,当条款 fulfilledresolved 已被仔细定义为具有不同的含义。

这就是这里发生的事情吗...右手不知道左手在做什么,而我们最终得到的文件应该是运动的指路明灯,但使用了不一致的术语?还是我遗漏了什么,对于resolve() 方法的作用,resolve 实际上是比 fulfill 更合适的术语?

我并不是要批评文档作者。我理解,对于一个分布广泛的群体,在历史上,很难让所有术语在所有文档中一致使用。我在这里深入研究这些文档的术语和措辞的目的是准确理解这些术语——这包括了解fulfillresolve 等术语的精确度限制真的可以区分。 Jake Archibald admits 他有时会把条款搞混。对于像我这样试图理解术语的新手来说,这是一个非常有用的承认!谢谢你,杰克,因为你很脆弱。 :-) 我问这个问题的目的是找出这些术语的哪些定义或用法可靠的?或者我应该得出结论,resolve 有时专门用于表示 fulfill,有时也用于表示 fulfill/reject/lock in,即使在最权威的文件中也是如此?

【问题讨论】:

  • 我同意,fulfill(ed) 与 resolv(ed) 的这种不一致的用法是一个真正的烦恼,当我第一次开始使用 Promises 时,它让我绊倒了好几次。话虽如此,我不确定是否有“答案”,因为它就是这样:p

标签: javascript terminology es6-promise


【解决方案1】:

我正在为 resolveresolvedfulfillfulfill 的基本概念而苦苦挣扎。

看看What is the correct terminology for javascript promises。是的,它们有时会混淆,但让我们尽量忽略这一点。

然而,规范使用 fulfillresolve 引用 then() 方法(或其相应的抽象概念)的第一个参数。我们最终是否以不一致的方式使用了本应成为运动指路明灯的文件?

不,这里没有矛盾,规范中的术语是准确的。

resolve 不是 reject 的反面,onFulfilled 回调也不完全对应resolving

或者我缺少什么,对于resolve() 方法的作用,resolve 实际上是一个比 fulfill 更合适的术语?

是的。问题是你可以resolve 用一个promise(或者一般来说,一个thenable,即任何带有then 方法的对象),而不是用那个对象来实现,resolved 的promise 将尝试去实现使用 thenable 的 result。或者当 thenable 有(将有)错误时,它会以此为由拒绝。

[在 MDN 中] 没有提到 Promise.resolve() 方法有可能拒绝

实际上有:“返回的 promise 将“跟随”那个 thenable,采用它的最终状态”。如果最终状态是错误状态,那么返回的 Promise 也会被拒绝。

Promise.reject() 方法,但没有Promise.fulfill() 方法。所以这里,reject的对应物是resolve,而不是fulfill

是的,ES6 Promise 缺少 Promise.fulfill 方法。起初这有点不一致和令人困惑,但这样做是有充分理由的:它会阻止您拥有一个由另一个 Promise 实现的 Promise。你只能resolve ES6 Promise,当你传入一个 Promise 时,它​​会获取它的结果而不是 Promise 对象本身。

这非常有用,但也可能非常不方便。有些库做得更好并允许这种情况,它们就是所谓的“代数承诺”(你可以更好地推理)。 Creed 就是一个很好的例子,它的 Promise.of 方法是 Promise.reject 的真正对应物。

【讨论】:

  • 谢谢,这很有帮助。当你说“用 X 解决”、“用 X 完成”或“用 X 拒绝”时,这是否意味着将 X 作为参数传递给相应的函数?或者“with X”在这三种情况下是否意味着不同的东西?
  • 另外,在“当你传入一个promise时,它会得到它的结果而不是promise对象本身”,你能否澄清两个it的前因,以及详细说明take这个词?我的猜测是:“如果你resolve() 一个promise,将另一个promise 作为参数传递给resolve(),第一个promise 的结果将是传递的promise 的result,而不是传递的promise对象本身。”
  • @LarsH 是的,这正是我的意思(在所有情况下)。
【解决方案2】:

让我们在您的引文中的其他地方添加重点:

如果尝试解决或拒绝承诺无效,则承诺已解决,即承诺已“锁定”以遵循另一个承诺,或者已被履行或拒绝

reject() 会将您的 Promise 和所有先前链接的状态更改为 rejected
虽然resolve() 将锁定您当前的 Promise,但只有解决回调的实现才会将其状态设置为fulfilled。只要一切都没有完成,你的 Promise 仍然是'pending'

例如,如果您确实链接了 Promise,并且在链接期间抛出了错误,那么您的 Promise 的状态将设置为 'rejected'

var p = new Promise((resolve, reject) => {
  resolve(); // here p is resolved, we can't call resolve() or reject() anymore
}).then((e) => { // chain it
  return new Promise((resolve, reject) => {
    console.log(p); // 'pending' because it's still chained
    reject('whatever') // this one throws an error and breaks the chain
  })
}).then(() => console.log('passed')); // won't happen


setTimeout(() => console.log(p, "please check in your browser's console"), 1000); // rejected

所以即使你是resolve()-ing你的Promise的当前操作,你也不知道之后会发生什么,所以你不知道最后是fulfilled还是rejected .

【讨论】:

  • 谢谢。我认为这很有帮助,尽管我仍然没有完全遵循逻辑。当您说“但只有解析回调的实现才会将其状态设置为fulfilled”时,解析回调指的是什么...作为resolve参数传递给提供给每个 Promise 构造函数的函数?
  • @LarsH,我把它看成一个链条。您解决了第一个链接,然后是以下链接。但只有在所有环节都解决后,链中的每一个 Promise 才会被履行。如果在某一时刻,一个链接断开,整个链 os 断开,所有的承诺都将被拒绝(无法实现最初的承诺......)
猜你喜欢
  • 2011-05-15
  • 1970-01-01
  • 2011-07-11
  • 2014-08-15
  • 1970-01-01
  • 2015-05-23
  • 1970-01-01
  • 2014-01-23
  • 1970-01-01
相关资源
最近更新 更多