ES6 - 决定对象还是承诺

Pat*_*nič 2 javascript promise ecmascript-6

是否有一种简单而优雅的方法来确定变量是否是javascript(es6)中的promise或object?

我有一个变量

let payment;
Run Code Online (Sandbox Code Playgroud)

并且在应用程序中,它可以是具有实际值的承诺或对象.我知道我可以测试它包含一些属性,如

if (payment.amount)
Run Code Online (Sandbox Code Playgroud)

但这对我来说似乎不是一个优雅的解决方案,因为属性(数据结构)可以及时改变.直到现在我正在使用

if (typeof payment === 'object')
Run Code Online (Sandbox Code Playgroud)

但我刚想通了,承诺基本上也是对象.所以这种情况总是如此.

是否可以判断它是真实数据的承诺还是对象?

lon*_*day 12

不要试图找出答案.只是让它永远是一个承诺.

payment = Promise.resolve(payment);
Run Code Online (Sandbox Code Playgroud)

Promise.resolve创建一个新的promise对象.如果传递的值本身就是一个promise,则在原始值被解析或拒绝时.如果是其他任何内容,则使用该值立即解决新承诺.


Ber*_*rgi 10

与所有其他本机对象一样,您可以instanceofPromise构造函数一起使用:

if (payment instanceof Promise)
Run Code Online (Sandbox Code Playgroud)

但是,如果您不知道它是本机承诺还是来自自定义库,您通常希望通过检查它是否有方法来检测thenable.then

但是你永远不需要区分它们(除了用于调试目的)。如果有可能是承诺,您将始终需要等待,并且无论如何都要从中构建承诺。您不需要自己进行区分,您可以使用Promise.resolve将 promise、thenable 或普通对象转换为您喜欢的实现的承诺 - 这就是 Promise 互操作性的最初设计方式,因此它绝对可以工作。

const promise = Promise.resolve(payment).then(value => {
    // value: always a plain value
}); // promise: always a promise
Run Code Online (Sandbox Code Playgroud)


Frx*_*rem 6

检查它是否具有then作为函数的属性:

if(payment != null && typeof payment.then === 'function')
  // is a promise
else
  // is not a promise
Run Code Online (Sandbox Code Playgroud)

据我所知,这是检查某事是否是承诺(或“类似承诺”的 thenable)的唯一正确方法,考虑到所有不同的可能承诺实现。