本文摘自PHP中文网,作者青灯夜游,侵删。

JavaScript不具有 sleep()
函数,该函数会导致代码在恢复执行之前等待指定的时间段。如果需要JavaScript等待,该怎么做呢?
假设您想将三则消息记录到Javascript控制台,每条消息之间要延迟一秒钟。JavaScript中没有 sleep()
方法,所以你可以尝试使用下一个最好的方法 setTimeout()
。
不幸的是,setTimeout()
不能像你期望的那样正常工作,这取决于你如何使用它。你可能已经在JavaScript循环中的某个点上试过了,看到 setTimeout()
似乎根本不起作用。
问题的产生是由于将 setTimeout()
误解为 sleep()
函数,而实际上它是按照自己的一套规则工作的。
在本文中,我将解释如何使用 setTimeout()
,包括如何使用它来制作一个睡眠函数,使JavaScript暂停执行并在连续的代码行之间等待。
浏览一下 setTimeout()
的文档,它似乎需要一个 "延迟 "参数,以毫秒为单位。
回到原始问题,您尝试调用 setTimeout(1000)
在两次调用 console.log()
函数之间等待1秒。
不幸的是 setTimeout()
不能这样工作:
1 2 3 4 5 6 7 8 9 10 11 |
|
这段代码的结果完全没有延迟,就像 setTimeout()
不存在一样。
回顾文档,你会发现问题在于实际上第一个参数应该是函数调用,而不是延迟。毕竟,setTimeout()
实际上不是 sleep()
方法。
你重写代码以将回调函数作为第一个参数并将必需的延迟作为第二个参数:
1 2 3 4 5 6 7 |
|
这样一来,三个console.log的日志信息在经过1000ms(1秒)的单次延时后,会一起显示,而不是每次重复调用之间延时1秒的理想效果。
在讨论如何解决此问题之前,让我们更详细地研究一下 setTimeout()
函数。
检查setTimeout ()
你可能已经注意到上面第二个代码片段中使用了箭头函数。这些是必需的,因为你需要将匿名回调函数传递给 setTimeout()
,该函数将在超时后运行要执行的代码。
在匿名函数中,你可以指定在超时时间后执行的任意代码:
1 2 3 4 |
|
理论上,你可以只传递函数作为第一个参数,回调函数的参数作为剩余的参数,但对我来说,这似乎从来没有正确的工作:
1 2 |
|
人们使用字符串解决此问题,但是不建议这样做。从字符串执行JavaScript具有安全隐患,因为任何不当行为者都可以运行作为字符串注入的任意代码。
1 2 |
|
那么,为什么在我们的第一组代码示例中 setTimeout()
失败?好像我们在正确使用它,每次都重复了1000ms的延迟。
原因是 setTimeout()
作为同步代码执行,并且对 setTimeout()
的多次调用均同时运行。每次调用 setTimeout()
都会创建异步代码,该代码将在给定延迟后稍后执行。由于代码段中的每个延迟都是相同的(1000毫秒),因此所有排队的代码将在1秒钟的单个延迟后同时运行。
相关阅读 >>
更多相关阅读请进入《javascript》频道 >>

Vue.js 设计与实现 基于Vue.js 3 深入解析Vue.js 设计细节
本书对 Vue.js 3 技术细节的分析非常可靠,对于需要深入理解 Vue.js 3 的用户会有很大的帮助。——尤雨溪,Vue.js作者