非 Promise 值的“等待”无效(Bluebird 承诺)

Posted

技术标签:

【中文标题】非 Promise 值的“等待”无效(Bluebird 承诺)【英文标题】:Invalid 'await' of a non-Promise value (Bluebird promise) 【发布时间】:2018-05-18 03:06:37 【问题描述】:

当我使用 tslint --project tsconfig.json src/**/*.ts 对整个项目进行 tslint 时,我会收到很多类似以下的 tslint 错误:

非 Promise 值的“等待”无效。

这些错误出现在我等待 Bluebird 承诺的每一行中。我想知道我应该怎么做才能避免这些警告?在运行时我没有遇到任何问题,但是我认为有充分的理由来解决这些问题?

例如,我正在使用 amqplib 库,它使用 Bluebird 来实现所有承诺。每次等待基于 promise 的方法之一时,我都会收到一个 tslint 错误:

const queueInfo: Replies.AssertQueue = await this.channel.assertQueue(this.jobQueueName);

问题:

等待非 Promise 值(如 Bluebird Promise)的最佳方式是什么?

【问题讨论】:

听起来像是打字的问题。 ampqplib 如何定义其方法返回的类型? 在启用类型检查的情况下对 await Bluebird.resolve(3); 进行 linting 时会出现相同的错误。 【参考方案1】:

看起来 TSLint 包含一个设置,用于指示在 await 表达式中将哪些类型视为承诺:

https://palantir.github.io/tslint/rules/await-promise/

我自己没有尝试过,但看起来你应该能够使用它来等待 Bluebird 的承诺:

"await-promise": [true, "Bluebird"]

【讨论】:

哦,这是一个非常好的发现。如果 tslint 能够在 Bluebird 和非承诺(如数字)之间有所不同(如您的评论中所示),为什么他们不允许在 microsoft-contrib 指南中使用它? @kentor 我没有说 tslint 能够区分承诺[-like object] 和非承诺。我刚刚说过 Github 上那个帖子的初衷似乎是关于根本不是承诺的事情,正如我所说,该帖子的最终结论至少是情况太模糊,无法制定任何硬性规则关于它(我假设当前的规则是在其他地方决定的)。关于 MS 贡献指南,可能是他们并不热衷于在他们的贡献中允许非本地承诺,因此不会特意允许它们。【参考方案2】:

您可以使用Promise.resolve 将任何“thenable”对象(至少使用then() 方法)转换为本机Promise

const queueInfo: Replies.AssertQueue = await Promise.resolve(this.channel.assertQueue(this.jobQueueName));

替代语法(有点因为闭包而效率低下):

const queueInfo: Replies.AssertQueue = await Promise.resolve().then(() =>
    this.channel.assertQueue(this.jobQueueName)
);

【讨论】:

我有点失望Promise.resolve(bluebirdPromsie) 会引入另一个 Promise。但显然目前没有更好的方法来等待非原生 Promise? @kentor await bluebirdPromise 是等待非本地承诺的好方法。如果有的话,问题在于你的 linter(或 TypeScirpt),而不是 promise。 @JLRishe tslint 错误是设计使然,请参阅:github.com/Microsoft/TypeScript/issues/8310。 @kentor 我不认为那是该线程所说的。 Ryan Cavannaugh 关闭它说没有可靠的方法来断言用户所做的事情是不正确的。该线程的全部重点是关于人们等待不是任何形式的承诺的事情(例如5)。

以上是关于非 Promise 值的“等待”无效(Bluebird 承诺)的主要内容,如果未能解决你的问题,请参考以下文章

Apollo 客户端错误,对象作为 React 子级无效(发现:[object Promise])

从异步等待函数中获取 Bluebird Promise

如何从fetch获取响应值而不是没有值的promise?

透彻掌握Promise的使用

promise和async/await

promise和async/await