async-await/阻塞机制理解是否正确?编程范式调整疑问
核心结论
你的理解是错误的。
你写的这段代码本身没有逻辑问题:await关键字会暂停当前async函数内部的执行流,直到后面跟着的异步操作(fetchSomethingFromDb()返回的Promise)状态变为已完成,才会把异步返回的结果赋值给userId,接着才会执行下一行const userEmail = getEmailAddy(userId)的逻辑。执行到这行时userId已经拿到了异步操作的正确返回值,不会因为异步没跑完变成undefined——除非fetchSomethingFromDb()本身resolve的就是undefined,或者异步请求抛错了你没有做异常捕获。
实际上async/await语法的设计初衷,就是让开发者可以用接近同步编程的写法来写异步逻辑,你现在的写法思路完全符合这个语法的设计目标,根本不算思维定式错误。
关于编程范式调整
你不需要彻底转变编程范式,只需要在现有写法基础上补几个关键认知、做小范围调整即可,完全没必要硬转回回调嵌套、长链式.then()这类可读性更差的写法:
- 记清
await的阻塞范围:它只会暂停当前所在async函数的执行,不会阻塞整个程序的其他同步任务、宏任务/微任务执行,不会把整个程序卡住。 - 独立异步任务不要串行await:如果多个异步操作之间没有依赖关系,不要挨个写
await把并行执行的任务改成串行,白白增加耗时,这种场景用Promise.all同时发起所有请求,再统一等待结果即可,示例:
// 错误写法:两个请求串行,总耗时是两个请求耗时之和 const userInfo = await fetchUserInfo() const orderList = await fetchOrderList() // 正确写法:两个请求并行,总耗时是耗时更长的那个请求的时间 const [userInfo, orderList] = await Promise.all([ fetchUserInfo(), fetchOrderList() ])
- 记得加异常处理:
await的异步操作如果抛错(比如网络请求失败、数据库查询报错),会直接抛出异常,需要用try/catch块包裹对应逻辑,或者给Promise加.catch()分支处理错误,避免异常击穿导致程序崩溃。 - 注意async函数的返回值:所有加了
async关键字的函数,返回值永远是Promise对象,如果你要在函数外部拿它的执行结果,要么在另一个async函数里await调用,要么用.then()接收结果,不能直接像同步函数那样拿返回值。
内容的提问来源于stack exchange,提问作者Rollor
相关产品推荐
相关产品推荐

