如何在Promise的finally方法中执行另一个Promise?
问题解答
1. 报错原因
这个报错不是代码语法错误,是ESLint校验规则触发导致的,和配置有关,核心原因有两个:
- 旧版ESLint核心规则
no-unsafe-finally默认禁止在finally块中返回任何值,包括Promise。规范层面虽然支持等待finally回调返回的Promise,但该规则认为finally的核心作用是执行清理逻辑,返回值(尤其是异步返回值)很容易出现预期外的行为:比如前面的Promise链已经成功,但finally里的writeFile报错的话,整个链的最终状态会变成失败,这个隐式逻辑很容易被忽略,因此规则默认判定这种写法有风险。 - 如果你用的是TypeScript相关的ESLint规则,
@typescript-eslint/no-misused-promises的checksVoidReturn配置开启后,会校验到finally回调的类型定义是() => void,你返回Promise类型的值和期望的void返回类型不匹配,因此抛出类型错误。
2. 写法是否属于坏味道
取决于你的业务预期:
- 如果你明确需要writeFile的状态覆盖前面Promise链的状态:比如如果写入文件失败,不管下载是否成功,都要让整个调用链返回失败,那这个写法逻辑是成立的,不属于坏味道,你只需要调整ESLint配置,忽略对应行的规则校验即可:
return this.downloadProject(data) // eslint-disable-next-line no-unsafe-finally,@typescript-eslint/no-misused-promises .finally(() => { return fse.writeFile('', 'foo'); }) - 如果你不需要writeFile的错误影响外层链的状态:即不管写入是否成功,都要保留前面downloadProject的执行结果,那这个写法就是坏味道。此时你不需要返回writeFile的Promise,只需要在回调内部处理写入逻辑、自行捕获写入错误即可,也不会触发ESLint报错:
return this.downloadProject(data) .finally(() => { fse.writeFile('', 'foo').catch(err => { // 自行处理写入错误,比如打印日志 console.error('文件写入失败', err) }) })
内容的提问来源于stack exchange,提问作者HelloWorld
相关产品推荐
相关产品推荐

