首页 文章

“决心”是否始终意味着与“履行”不同的东西?

提问于
浏览
6

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

我挣扎着解决和解决的基本概念,而不是履行和实现 . 我已阅读了几篇介绍,例如Jake Archibald's,以及浏览some relevant specs .

States and Fates(不是一个官方规范,但被一个规范作者编写的权威文档引用),履行是一个状态,而解决的是"fate"(无论是什么 - 但它们明显不同):

承诺有三种可能的互斥状态:履行,拒绝和待决 . 如果promise.then(f)将尽快调用f,则履行承诺 .

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

特别是,已解决包括已履行和已拒绝(并已锁定) . 要拒绝的"opposite"(或直接相应的功能)是履行,而不是解决;解决 includes 拒绝作为其可能性之一 .

然而spec使用完成和解析来引用 then() 方法(或其相应的抽象概念)的第一个参数:

  • 25.4:如果p.then(f,r)将立即将作业排入队列以调用函数f,则履行了承诺p .

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

  • 25.4.1.3:将[[Promise]]内部插槽设置为promise . 将resolve的[[AlreadyResolved]]内部插槽设置为alreadyResolved . [然后立即以完全相应的方式使用拒绝 . ]

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

也许其中最重要的是

  • 25.4.4.5 Promise.resolve(x)

MDN描述如下:

Promise.resolve(value)方法返回使用给定值解析的Promise对象 . 如果该值是一个可设置的(即具有“then”方法),则返回的promise将“跟随”那个可能的,采用其最终状态;否则返回的承诺将通过该值来实现 .

没有提到有可能拒绝的 Promise.resolve() 方法 . 此外,还有一个 Promise.reject() 方法,但没有 Promise.fulfill() 方法 . 所以在这里,拒绝的对手是解决,而不是履行 .

当然,"fate"术语已解决,方法(或动词)解析可能没有保证相关性 . 但是,当履行和解决的条款被认真地定义为具有不同的含义时,将某个承诺转变为一个特定的履行状态会是(实际上是)误导和混淆 .

这就是发生在这里的事情......右手没有错过,而解决方案实际上是一个比 resolve() 方法所做的更合适的术语吗?

我很难在所有文件中一致地使用所有条款 . 我在这里挖掘这些文件的术语和措辞的目的是准确理解这些术语 - 其中包括了解如何真正区分完成和解决等术语的限度 . Jake Archibald admits他有时会把条款混淆起来 . 对于像我这样试图理解术语的新手来说,这是一个非常有用的录取!杰克,谢谢你的弱势 . :-)我提出这个问题的目的是要找出这些术语的哪些定义或用法是可靠的?或者,我是否应该得出结论,即使在最权威的文档中,有时也会特别使用解决方案来表示实现,有时候实现/拒绝/锁定?

2 回答

  • 2

    我正在努力解决决心和解决的基本概念,而不是履行和实现 .

    看看What is the correct terminology for javascript promises . 是的,他们试图忽略这一点 .

    然而,规范引用了then()方法(或其相应的抽象概念)的第一个参数,使用完成和解析 . 我们是否以不一致的方式结束了应该成为运动指导灯的文件?

    不,这里没有矛盾,规范中的条款是准确的 .

    resolve不是拒绝的反义词, onFulfilled 回调并不完全对应于解析 .

    或者是否有一些我缺少的东西,而且解决方案实际上是一个更合适的术语,而不是满足于什么resolve()方法呢?

    是 . 问题是你可以用一个promise(或者一般来说,就是一个具有 then 方法的任何对象)来解决,而不是用该对象来实现解析的promise将尝试用thenable的结果来实现 . 或者当那个人有(会有)一个错误时,它会拒绝那个原因 .

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

    实际上有:“返回的承诺将是"follow",然后才能采用其最终状态” . 如果该最终状态是错误状态,则返回的promise也将拒绝 .

    有一个Promise.reject()方法,但没有Promise.fulfill()方法 . 所以在这里,拒绝的对手是解决,而不是履行 .

    是的,ES6承诺缺乏 Promise.fulfill 方法 . 这一点有点不一致和令人困惑,但是有充分理由这样做:它阻止你有一个履行另一个承诺的承诺 . 您只能解析ES6承诺,当您传递承诺时,它将自己的结果而不是承诺对象 .

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

  • 1

    让我们在其中一个引号中强调其他地方:

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

    reject() 会将您的承诺和所有先前链接的状态更改为 rejected .
    虽然 resolve() 将锁定您当前的Promise,但只有解析回调的实现才会将其状态设置为 fulfilled . 只要一切都没有完成,你的承诺仍然是 '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
    

    因此,即使你是你的承诺的当前操作,你也可以't know what will happen after, so you can'知道最后它是 fulfilled 还是 rejected .

相关问题