setTimeout为何同步执行?回调传参错误导致无延迟问题排查
问题原因
setTimeout的第一个参数必须是待延迟执行的函数引用,你当前的写法直接把console.log("hi-async")作为参数传入,JS在执行函数调用时,会先同步计算所有入参的值,这一步就会立刻执行console.log("hi-async")完成打印,再把这条语句的返回值undefined传给setTimeout。
你的代码实际执行顺序是:
- 运行第一行代码,同步打印
hi1 - 运行第二行代码:
- 先计算第一个入参的值:直接执行
console.log("hi-async"),同步打印hi-async,得到返回值undefined - 调用
setTimeout,传入无效回调undefined和1000毫秒延迟,1秒后因为没有合法回调可执行,不会有任何输出
- 先计算第一个入参的值:直接执行
- 运行第三行代码,同步打印
hi3
所以你会看到三个日志一次性按hi1、hi-async、hi3的顺序输出,完全没有等待延迟。
修正方案
把需要延迟执行的逻辑包裹在函数中传入setTimeout,保证引擎会在延迟到期后再调用这个函数、执行内部的打印逻辑:
console.log("hi1"); setTimeout(function() { console.log("hi-async") }, 1000); console.log("hi3");
箭头函数写法效果完全一致:
console.log("hi1"); setTimeout(() => console.log("hi-async"), 1000); console.log("hi3");
也可以直接传入console.log作为回调,把要打印的内容作为后续参数传给setTimeout,它会在执行回调时自动把参数透传进去:
console.log("hi1"); setTimeout(console.log, 1000, "hi-async"); console.log("hi3");
以上三种写法都能得到你预期的输出:先打印hi1、hi3,等待1秒后打印hi-async。
内容的提问来源于stack exchange,提问作者Maximilian
相关产品推荐
相关产品推荐

