【问题标题】:Detect missing await in JavaScript methods in VSCode检测 VSCode 中 JavaScript 方法中缺少的等待
【发布时间】:2021-07-14 10:08:31
【问题描述】:

我正在寻找一些 eslint 选项,或者在调用类中的异步方法之前检测缺少 'await' 关键字的其他方法。考虑以下代码:

const externalService = require('./external.service');

class TestClass {

constructor() { }

async method1() {
    if (!await externalService.someMethod()) {
        await this.method2();
    }
}

async method2() {
    await externalService.someOtherMethod();
}

module.exports = TestClass;

如果我将method1转换为:不会有警告

async method1() {
    if (!await externalService.someMethod()) {
        this.method2();
    }
}

我尝试在“.eslintrc”文件上做:

"require-await": 1,
"no-return-await": 1,

但没有运气。任何人都知道它是否可能? 非常感谢!

【问题讨论】:

  • 在没有 await 的情况下调用 async 函数实际上是完全有效的,你只是得到一个 Promise 作为回报,所以我怀疑 linter 允许这种规则(这是非常严格的)
  • @GuerricP 我编辑了代码,method2会调用外部方法(假设你不知道里面的代码是什么,它是第三方代码)。
  • 您或许可以使用规则no-floating-promises。它的行为略有不同,但我认为它会抓住这种情况。
  • @Automatico,谢谢,会检查的。

标签: javascript node.js visual-studio-code eslint eslintrc


【解决方案1】:

typescript-eslint 对此有一个规则:no-floating-promises

此规则禁止在未适当处理其错误的情况下在语句中使用类似 Promise 的值...处理 Promise 值语句的有效方法包括 awaiting、返回以及使用两个参数或 @ 调用 .then() 987654331@ 一个参数。

你可能从名字中知道,typescript-eslint 旨在为 eslint 添加 TypeScript 支持,但你也可以将它与 JavaScript 一起使用。我想这是你的决定,它是否对这条规则是矫枉过正的,但这里是步骤:

  1. 生成tsconfig.json 文件

    npx tsc --init
    
  2. 安装依赖

    npm install --save-dev eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser
    
  3. 修改您的.eslintrc 文件

    根据我的测试,您至少需要这些条目:

    {
      "parser": "@typescript-eslint/parser",
      "parserOptions": { "project": "./tsconfig.json" },
      "plugins": ["@typescript-eslint"],
      "rules": {
        "@typescript-eslint/no-floating-promises": ["warn"]
      }
    }
    

    (我将它设置为warn,因为as Quentin mentioned,有时您想调用一个返回Promise 的函数而不使用await。但如果您愿意,可以将其设置为error。 )

设置 typescript-eslint 的文档在此处获取更多信息:https://typescript-eslint.io/docs/linting/linting

下次运行 eslint 时,您应该会看到已应用的规则:

$ npm run lint
...
./services/jobService.js
  11:5  warning  Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator  @typescript-eslint/no-floating-promises

由于您特别提到了 VS Code,这也与 ESLint plugin 很好地集成:

【讨论】:

  • 这应该是公认的答案
【解决方案2】:

require-await 表示“不要创建函数 async,除非你在其中使用 await”。

这是因为async有两个作用:

  • 它强制函数返回一个承诺
  • 它可以让你在里面使用await

前者很少有用,这意味着如果您没有在函数中使用await,您需要质疑为什么将其标记为async


no-return-await 阻止你这样做:

return await something

因为await 会从promise 中解包一个值,但从async 函数返回的值会将其包装在promise 中。

由于只是返回一个承诺会导致该承诺被采用,因此将returnawait 组合起来只是臃肿。


所以这些都不是你想要的。

这将我们带入您的实际愿望。

ESLint 中不存在(据我所知)这样的功能,而且我认为拥有它不会有用。

在很多用例中,您不想等待 async 函数返回的内容。

例如

const array_of_promises = array_of_values.map( value => do_something_async(value) );
const array_of_resolved_values = await Promise.all(array_of_promises);

上面是一个常见的用例,您希望并行运行一堆异步函数,然后等待它们全部解决。

另一个例子是no-return-await被设计用来检测的情况!

这样的案例很常见,以至于大多数人不希望他们的工具链要求他们这样做。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-20
  • 2012-10-25
  • 2014-02-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多