为何async函数搭配setTimeout返回值无效,Promise却可以正常工作?
问题原因
你的核心错误是对async函数return的作用域理解有偏差:
async函数的return值会被自动包装为Promise.resolve的结果,但这个return必须是async函数本身的返回值,而非它内部嵌套函数的返回值。
你写的test1中,return 5是setTimeout回调函数的返回,仅用来结束回调本身的执行,完全不会传递到外层的test1函数。而test1同步执行完setTimeout调度后没有任何显式return,默认返回undefined,所以async函数会自动把这个undefined包装为已完成状态的Promise,await拿到的结果自然是undefined。
而test2的逻辑是成立的,因为你把setTimeout包裹在了Promise实例中,回调里调用的resolve就是用来变更这个Promise状态的方法,因此await可以正常拿到返回值。
关于async/await的本质
async/await就是Promise的语法糖,没有新增任何异步处理能力,它的作用就是替代链式.then()调用,简化Promise的书写流程:await会暂停当前async函数的执行,等待后方的Promise状态变为已完成后,将resolve的结果作为await表达式的返回值再继续执行后续逻辑,和.then()的回调处理逻辑完全等价。
关于return替代resolve的使用条件
只要满足作用域要求就可以用async函数的return替代Promise.resolve:这个return必须是async函数顶层的返回,不能是内部嵌套的回调、其他子函数的返回。
如果你的异步逻辑依赖回调实现(比如setTimeout、传统回调式API),你必须先把这部分逻辑手动包装为Promise实例,才能搭配async/await使用,不能直接把回调内部的return当作async函数的返回。举个正确改写test1的例子:
const test1 = async () => { // 先把setTimeout包装成Promise return new Promise((resolve) => { setTimeout(() => { resolve(5); }, 2000); }) }
内容的提问来源于stack exchange,提问作者David

