为何wait函数的执行时间随调用次数增加而变长?
问题:为什么wait函数的执行时间随调用次数增加而持续变长?
代码示例
fetchAsync().then() async function fetchAsync() { return await Promise.all([...Array(1000).keys()].map((i) => wait(i))) } async function wait(i) { const startTime = Date.now(); await new Promise(resolve => { setTimeout(() => resolve(), 100) }); const timePassed = Date.now() - startTime; console.log(`Call ${i}: ${timePassed}ms`) }
控制台输出
Call 0: 102ms Call 1: 108ms Call 2: 109ms Call 3: 109ms Call 4: 109ms Call 5: 110ms ... Call 995: 190ms Call 996: 190ms Call 997: 190ms Call 998: 190ms Call 999: 190ms
可以看到,wait函数的执行时间随调用次数增加而持续变长,请问这是什么原因导致的?
原因分析
- 事件循环任务队列阻塞:一次性创建的1000个setTimeout回调会被加入宏任务队列。虽然每个定时器设置的是100ms后触发,但事件循环需要逐个处理这些任务。前面的回调执行(包括console.log操作)会占用时间,导致后续回调被延迟执行,时间差自然被拉长。
- console.log的累积开销:console.log需要和浏览器控制台交互,属于相对耗时的操作。1000次日志输出的累积开销会进一步推迟后续回调的执行,越靠后的wait函数,从计时开始到实际完成的时间差就越大。
- setTimeout的精度限制:JavaScript的setTimeout无法保证精确计时,它只能确保回调在指定时间后被加入任务队列,而非精确在该时间点执行。当任务队列繁忙时,实际执行时间会被延后,任务数量越多,延后效果越明显。
内容的提问来源于stack exchange,提问作者Jan
相关产品推荐
相关产品推荐

