原文地址:https://www.jb51.net/article/210876.htm

JavaScript不具有 sleep()函数,该函数会导致代码在恢复执行之前等待指定的时间段。如果需要JavaScript等待,该怎么做呢?

假设您想将三则消息记录到Javascript控制台,每条消息之间要延迟一秒钟。JavaScript中没有 sleep() 方法,所以你可以尝试使用下一个最好的方法 setTimeout()。

不幸的是,setTimeout() 不能像你期望的那样正常工作,这取决于你如何使用它。你可能已经在JavaScript循环中的某个点上试过了,看到 setTimeout() 似乎根本不起作用。

问题的产生是由于将 setTimeout() 误解为 sleep() 函数,而实际上它是按照自己的一套规则工作的。

浏览一下 setTimeout() 的文档,它似乎需要一个 "延迟 "参数,以毫秒为单位。

回到原始问题,您尝试调用 setTimeout(1000) 在两次调用 console.log() 函数之间等待1秒。

不幸的是 setTimeout() 不能这样工作:

1

2

3

4

5

6

7

8

9

10

11

setTimeout(1000)

console.log(1)

setTimeout(1000)

console.log(2)

setTimeout(1000)

console.log(3)

for (let i = 0; i <= 3; i++) {

  setTimeout(1000)

  console.log(`#${i}`)

}

这段代码的结果完全没有延迟,就像 setTimeout() 不存在一样。

回顾文档,你会发现问题在于实际上第一个参数应该是函数调用,而不是延迟。毕竟,setTimeout() 实际上不是 sleep() 方法。

你重写代码以将回调函数作为第一个参数并将必需的延迟作为第二个参数:

1

2

3

4

5

6

7

setTimeout(() => console.log(1), 1000)

setTimeout(() => console.log(2), 1000)

setTimeout(() => console.log(3), 1000)

for (let i = 0; i <= 3; i++) {

  setTimeout(() => console.log(`#${i}`), 1000)

}

这样一来,三个console.log的日志信息在经过1000ms(1秒)的单次延时后,会一起显示,而不是每次重复调用之间延时1秒的理想效果。

在讨论如何解决此问题之前,让我们更详细地研究一下 setTimeout() 函数。

检查setTimeout ()

你可能已经注意到上面第二个代码片段中使用了箭头函数。这些是必需的,因为你需要将匿名回调函数传递给 setTimeout(),该函数将在超时后运行要执行的代码。

在匿名函数中,你可以指定在超时时间后执行的任意代码:

1

2

3

4

// 使用箭头语法的匿名回调函数。

setTimeout(() => console.log("你好!"), 1000)

// 这等同于使用function关键字

setTimeout(function() { console.log("你好!") }, 1000)

理论上,你可以只传递函数作为第一个参数,回调函数的参数作为剩余的参数,但对我来说,这似乎从来没有正确的工作:

1

2

// 应该能用,但不能用

setTimeout(console.log, 1000, "你好")

人们使用字符串解决此问题,但是不建议这样做。从字符串执行JavaScript具有安全隐患,因为任何不当行为者都可以运行作为字符串注入的任意代码。

1

2

// 应该没用,但确实有用

setTimeout(`console.log("你好")`, 1000)

那么,为什么在我们的第一组代码示例中 setTimeout() 失败?好像我们在正确使用它,每次都重复了1000ms的延迟。

原因是 setTimeout() 作为同步代码执行,并且对 setTimeout() 的多次调用均同时运行。每次调用 setTimeout() 都会创建异步代码,该代码将在给定延迟后稍后执行。由于代码段中的每个延迟都是相同的(1000毫秒),因此所有排队的代码将在1秒钟的单个延迟后同时运行。

如前所述,setTimeout() 实际上不是 sleep() 函数,取而代之的是,它只是将异步代码排入队列以供以后执行。幸运的是,可以使用 setTimeout() 在JavaScript中创建自己的 sleep() 函数。

如何编写sleep函数

通过Promises,async 和 await 的功能,您可以编写一个 sleep() 函数,该函数将按预期运行。

但是,你只能从 async 函数中调用此自定义 sleep() 函数,并且需要将其与 await 关键字一起使用。

这段代码演示了如何编写一个 sleep() 函数:

1

2

3

4

5

6

7

8

9

10

11

const sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay))

const repeatedGreetings = async () => {

  await sleep(1000)

  console.log(1)

  await sleep(1000)

  console.log(2)

  await sleep(1000)

  console.log(3)

}

repeatedGreetings()

此JavaScript sleep() 函数的功能与您预期的完全一样,因为 await 导致代码的同步执行暂停,直到Promise被解决为止。

一个简单的选择

另外,你可以在第一次调用 setTimeout() 时指定增加的超时时间。

以下代码等效于上一个示例:

1

2

3

setTimeout(() => console.log(1), 1000)

setTimeout(() => console.log(2), 2000)

setTimeout(() => console.log(3), 3000)

使用增加超时是可行的,因为代码是同时执行的,所以指定的回调函数将在同步代码执行的1、2和3秒后执行。

它会循环运行吗?

如你所料,以上两种暂停JavaScript执行的选项都可以在循环中正常工作。让我们看两个简单的例子。

这是使用自定义 sleep() 函数的代码段:

1

2

3

4

5

6

7

8

9

const sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay))

async function repeatGreetingsLoop() {

  for (let i = 0; i <= 5; i++) {

      await sleep(1000)

    console.log(`Hello #${i}`)

    }

}

repeatGreetingsLoop()

这是一个简单的使用增加超时的代码片段:

1

2

3

for (let i = 0; i <= 5; i++) {

  setTimeout(() => console.log(`Hello #${i}`), 1000 * i)

}

我更喜欢后一种语法,特别是在循环中使用。

总结

JavaScript可能没有 sleep() 或 wait() 函数,但是使用内置的 setTimeout() 函数很容易创建一个JavaScript,只要你谨慎使用它即可。

就其本身而言,setTimeout() 不能用作 sleep() 函数,但是你可以使用 async 和 await 创建自定义JavaScript sleep() 函数。

采用不同的方法,可以将交错的(增加的)超时传递给 setTimeout() 来模拟 sleep() 函数。之所以可行,是因为所有对setTimeout() 的调用都是同步执行的,就像JavaScript通常一样。

希望这可以帮助你在代码中引入一些延迟——仅使用原始JavaScript,而无需外部库或框架。

以上就是如何使JavaScript休眠或等待的详细内容,更多关于JavaScript休眠或等待的资料请关注脚本之家其它相关文章!

JavaScript休眠或等待相关推荐

  1. JavaScript中异步/等待的用法和理解

    昨天更新的是"JavaScript中的Promise使用详解",其实也就是说了下基本用法和自己对Promise的理解,可能有错误之处,也欢迎指出.今天就说一说"JavaS ...

  2. 我如何在Node.js(Javascript)中等待,我需要暂停一段时间

    本文翻译自:How Can I Wait In Node.js (Javascript), l need to pause for a period of time I'm developing a ...

  3. 如何在Node.js(Javascript)中等待,我需要暂停一段时间?

    async function init(){console.log(1)await sleep(1000)console.log(2) } function sleep(ms){return new ...

  4. python 访问网页 重定向_Python数据网络采集5--处理Javascript和重定向

    Python数据网络采集5--处理Javascript和重定向 到目前为止,我们和网站服务器通信的唯一方式,就是发出HTTP请求获取页面.有些网页,我们不需要单独请求,就可以和网络服务器交互(收发信息 ...

  5. C#.Net网页加载等待效果漂亮并且简单

    最近网页加载数据比较多,点击后给用户就是白板很不友好,想了很久找了些资料,在网页加载中显示等待画面给客户,页面加载完成自动隐藏等待效果. 在网页后台cs代码:     protected void P ...

  6. android 休眠唤醒驱动流程分析,Android4.0.4休眠唤醒机制分析(基于MSM8260)

    当手机满足一定的条件时,会进入休眠状态.从手机进入休眠到唤醒,主要分为三个阶段: early suspend suspend late resume early suspend执行在休眠前需要完成的一 ...

  7. JavaScript 误区

    接触JavaScript两年多遇到过各种错误,其中有一些让人防不胜防,原来对JavaScript的误会如此之深,仅以此文总结一下常见的各种想当然的误区 String replace string的re ...

  8. 睡眠和休眠:常见问题

    以下是一些有关睡眠和休眠的常见问题解答. 睡眠.休眠和混合睡眠之间有什么区别? "睡眠"是一种节能状态,当您希望再次开始工作时,可使计算机快速恢复全功率工作(通常在几秒钟之内).让 ...

  9. [译]深入理解JavaScript函数执行—调用栈,事件循环和任务等

    Web 开发者,或者前端工程师(我们更喜欢别人这么称呼)现如今几乎能做所有的工作,从扮演一个浏览器内部交互性的角色,到制作电脑游戏.桌面控件.跨平台手机应用,甚至还可以把它写在服务器端(最流行的是no ...

最新文章

  1. vue vuex vue-router后台项目——权限路由(超详细简单版)
  2. ansible playbook中使用迭代with_items案例
  3. 关于移动端 1px 像素问题
  4. windows c语言 http https检测_C语言编程工具的选择
  5. 今天起高考能查分了!这种方式超方便的
  6. php多进程采集百度,php实现多进程下载百度网盘文件
  7. HTML(超文本语言)
  8. maven 打包父工程_maven 父子工程打包 并且上传linux服务器
  9. Windows 无法启动 vmwave workstation server 服务 错误1075
  10. 打印机扫描找不到计算机用户名,打印机扫描到pc显示不可用 打印机扫描到pc显示不可用的解决方法...
  11. 数据可视化|用热力地图进行数据分析
  12. php如何放照片,怎样在图片上加上自己的照片 在图片方框中嵌入另一张照片显示...
  13. 哪个更好:Revo卸载程序或免费替代方案?
  14. 图像检索:INS视觉检索
  15. 第一节计算机课要教什么作用,信息技术第一节课要求
  16. 哼唱识别(query by humming)
  17. 吴恩达:回顾2021,这些大事件影响了AI这一年
  18. 基于Mtk平台的android camera hal3学习
  19. QNX Neutrino 微内核
  20. WEB编程期末项目——我的第一个网站

热门文章

  1. 计蒜客NOIP模拟赛4 D2T1 鬼脚图
  2. Nginx 代理https
  3. 什么是Gratuitous ARP
  4. 网上申请的流量卡为何审核不通过,这些原因你中招了吗
  5. 线性代数之矩阵我们需要了解的知识点(增广矩阵矩阵的迹 矩阵的秩阶梯型...)
  6. 《自然语言处理(哈工大 关毅 64集视频)》学习笔记:第七章 句法分析技术
  7. bugku-逆向-6、逆向入门
  8. 2021年G2电站锅炉司炉最新解析及G2电站锅炉司炉模拟考试
  9. 题目:一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?
  10. pinyin4j把中文句子(含有多音字字母)转成拼音(二维数组递归求所有组合情况返回list)算法实现!...