Node.js中async函数调用setTimeout返回异常的原因及解决方法
核心原因
你需要先明确三个基础的JS运行规则:
- async函数的返回逻辑是:将函数内return语句的返回值自动包装为fulfilled状态的Promise,async本身不会自动等待未被Promise包裹的异步操作。
setTimeout本身是同步执行的,调用后会立刻返回定时器实例ID,不会等待定时结束。- setTimeout回调函数的返回值会被JS引擎直接忽略,你如果不主动把回调里的结果传给Promise的resolve方法,外部是拿不到这个值的。
各函数执行逻辑拆解
- 你认为
llamada1和llamada2逻辑一致是错误的:getNombre1中直接return字面量'A',所以async包装的Promise直接resolve出'A',和getNombre3手动new Promise后立刻resolve('A')逻辑完全对等。getNombre2中return的是setTimeout(...)的执行结果,也就是定时器实例,async只会把这个实例包装成Promise返回,根本不会等待3秒后的定时器回调执行,也拿不到回调里return的'B',所以你then里打印的就是定时器实例。
getNombre4和getNombre2逻辑完全不同:- 你手动把setTimeout包裹在了Promise内部,并且把
'B'传给了Promise的resolve方法,所以Promise会等待3秒后定时器触发resolve,才会把'B'作为结果返回,自然then里能拿到'B'。
- 你手动把setTimeout包裹在了Promise内部,并且把
修改getNombre2得到和getNombre4一致效果的方案
你需要手动把setTimeout包装为Promise,再通过async返回:
let getNombre2 = async() => new Promise(resolve => { setTimeout(() => resolve('B'), 3000) })
修改后调用getNombre2().then(t => console.log(t))就会在3秒后打印'B'。
内容的提问来源于stack exchange,提问作者Santy Perez
相关产品推荐
相关产品推荐

