在async函数中调用含await的async函数是否需添加await关键字?
关于async函数调用时是否需要await的问题
场景回顾
- 定义含await的无返回值async函数foo1:
const foo1 = async () => { const a1 = await something... // 示例:查询数据库的findValueInDatabase() }
- 定义含await的无返回值async函数foo2:
const foo2 = async () => { const a2 = await something... // 示例:发送邮件的sendEmail() }
- 在foo1中调用foo2时有两种写法:
const foo1 = async () => { const a1 = await something... foo2() // 写法1:无await // await foo2() // 写法2:带await ...some more code to be executed... }
疑问解答
两种写法有明显差异,你的预期是错误的,具体区别如下:
1. 执行顺序差异
- 直接写
foo2():foo2会启动执行,但foo1不会等待foo2完成,会立刻继续执行后续代码。foo2内部的await只会阻塞自身的代码流程,完全不影响foo1的执行节奏。比如foo2里是发送邮件的异步操作,foo1会直接跳过等待邮件发送完成的步骤,去跑后面的逻辑。 - 写
await foo2():foo1会暂停执行,直到foo2内部所有异步操作全部完成,才会继续执行后续代码。也就是必须等foo2的任务(比如邮件发送完成)结束后,foo1才会往下走。
2. 错误处理差异
async函数不管有没有返回值,都会返回一个Promise对象:
- 直接调用
foo2()时,如果foo2内部抛出错误,这个错误会变成未捕获的Promise拒绝,在浏览器里会触发控制台警告,在Node.js里甚至可能导致进程退出,而且你无法直接在foo1里捕获这个错误。 - 使用
await foo2()时,可以把它包裹在try/catch块中,直接捕获foo2内部的错误,避免未处理的异常:
const foo1 = async () => { const a1 = await something... try { await foo2() } catch (err) { // 处理foo2执行中的错误 console.error('foo2执行失败:', err) } ...some more code to be executed... }
内容的提问来源于stack exchange,提问作者Jakob Basshunter Widmann
相关产品推荐
相关产品推荐

