这可能是什么?[TsLint错误:“必须正确处理承诺”]


77

我正在使用async/awaitTypeScript做一些基本的异步操作,但是TSLint在下面的这两个函数中抛出了神秘的错误消息。有人遇到过这些错误吗?在错误输出中未提及控制规则,因此我不明白是什么原因造成的。任何想法将不胜感激。

主要要求:

import * as rp from 'request-promise'

export function getRequest(address: rp.Options): rp.RequestPromise {
  return rp(address)
}

导出异步功能:

export async function getStatus(message: Message) {
  try {
    const res = await getRequest(address)
    if (res.ready) {
      message.reply('...')
    } else {
      message.reply('...')
    }
  } catch (err) {
    message.reply(err)
  }
}

这得到:Promises must be handled appropriately并且await of non-Promise对于第3行。

使用此导出的简单功能是:

client.on('message', message => {
  if (message.content === 'green') {
    getStatus(message)
  }
})

这也得到了Promises must be handled appropriately

附加信息:

即使错误消息没有提及,这似乎仍然是以下规则Promises must be handled appropriatelyhttps : //palantir.github.io/tslint/rules/no-floating-promises/

这个问题提到了await of non-Promisehttps : //github.com/palantir/tslint/issues/2661


3
您还可以在问题中发布getRequest函数,谢谢。
Rikusor

好点,我已经添加了。
cinnaroll45年

只是在这里猜测,但这可能是tslint无法识别rp函数返回了promise。您可以尝试为其设置类型,导出函数getRequest(address:rp.Options):Promise <any> {...让我知道这是否有效,所以我不花更多时间检查它了:)
Rikusor

与IDE实际返回的内容不兼容,在IDE上返回Promise <any>错误rp。所以我用了这个:export function getRequest(address: rp.Options): rp.RequestPromise { return rp(address) }这可以满足IDE,但是在最初的帖子中我仍然遇到完全相同的错误。
cinnaroll45年

Answers:


111

这是一个糟糕的错误消息。一个更好的可能是

每个类型的表达式都Promise必须以对拒绝处理程序.catch.thensource的调用或调用结束

因此,例如,如果您这样做

PromiseFunction()
  .catch(err => handle(err))
  .then(() => console.log('this will succeed'))

那么您仍然会遇到tslint问题,因为的类型.then(...)是一个承诺,而且必须以失败告终。该修复程序将附加一个.catch子句,例如,

PromiseFunction()
  .catch(err => handle(err))
  .then(() => console.log('this will succeed'))
  .catch(() => 'obligatory catch')

或仅通过以下方式为该行禁用tslint:

PromiseFunction()
  .catch(err => handle(err))
  // tslint:disable-next-line:no-unsafe-any
  .then(() => console.log('this will succeed'))

或者,您可以颠倒.thenand.catch语句的顺序。但是,.then如果确实发生错误,这将停止执行,如果遇到此问题,您可能希望这样做。


26
嗨,艾略特(Elliot)-我写下了no-floating-promises规则,并同意错误消息不是很好。如果您想发送更详尽的描述,我全力以赴!
乔什(Josh)

57

有时您可能想兑现承诺,但是您无需对响应做任何事情。路线变更或其他。

所以代替:

promiseFunction().then().catch()
try/catch async/await

你可以做:

void promiseFunction();

5
很好,这很有效,看到void语法的引用很方便
Damian Green

这很好用,但是对我而言,我在任何地方的任何文档中都找不到对此的任何引用。
ACH

1
显然,这是JavaScript“ void”运算符
ACH

在调用的函数前面放一个空格是可行的。
Sarthak Srivastav

不要使用这个。您只是对其进行了混淆。这仍然是一个浮动的承诺。这是一种不常见的用法。
多米尼克

6

当我创建firebase-function使用时,我有同样的异常firebase-tool

const ref = admin.database().ref("path/to/database/object");

ref.once("value").catch(error =>{  // line 22
    response.send( error() );
}).then( snapshot =>{
    response.send( snapshot.val );
})

此代码未编译, return

ERROR: /src/index.ts[22, 5]: Promises must be handled appropriately

我已更改catch和的位置then

ref.once(...).then(...).catch(...)

该代码有效,很抱歉,但没有任何解释

当应用程序返回一些错误而没有 catch阻塞即使firebase doc没有提到catch所需的东西,也是。


4

您的getStatus函数定义为返回承诺:

// All functions marked as async returns a promise:
async function getStatus(message: Message) {/* ... */}

但是您getStatus没有打电话就打电话给了:

getStatus(message)

因此,编译器认为您已经忘记了处理异步代码。您所需要做的就是致电.then()

getStatus(message).then(() => console.log('done'));

您说的对,但是这条线getStatus(message).then(() => console.log('done'))仍然正确Promises must be handled appropriately
cinnaroll45 '17

@ cinnaroll45您是否也尝试过处理.catch()getStatus().then().catch()
slebetman

是的,尝试了bot.catch()和atry/catch来调用getStatus()仍然与我的第一个注释相同的错误。
cinnaroll45 '17

1
@ cinnaroll45您能够解决此问题吗?我也遇到同样的问题,无法解决
Prafful Garg

1
我拒绝投票是因为这是错误的,tslint正在寻找捕获或带有拒绝处理程序的.then。
好战的黑猩猩

1

我认为这个问题可以通过等待getStatus函数来解决,因为它是异步函数。该消息说的很清楚,但是行号引起混乱。老实说,这也花了我一些时间。

您可以通过以下代码更改来解决此皮棉错误:

client.on('message', message => {
 if (message.content === 'green') {
   await getStatus(message)
}});

我认为关闭这些特定错误不是一个好主意。它们很有用,因为以另一种方式,您将不会异步运行代码。


1
这将改变代码的行为。在添加之前awaitgetStatus不会占用该线程。作者可能不希望延迟后续执行。这可能不必要地拖延了一个应用程序。
jmealy

1

如果您要使用typescript-eslint编写一个无效的异步函数,那么在不等待的情况下编写异步函数将引起抱怨,这很容易忘记,尤其是对于函数的最后一行。

const sendSyncPlayCommandToWatchers = async (): Promise<void> => {
  ...
  someAsyncFunction()
}

你会得到

错误必须正确处理承诺@ typescript-eslint / no-floating-promises

您需要将await关键字添加到最后一行(或确保按照前面的答复中所述,使用try / catch处理诺言

const sendSyncPlayCommandToWatchers = async () => {
  ...
  await someAsyncFunction()
}

我认为这也将有助于在调试时获得更好的堆栈跟踪。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.