概述

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

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

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

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

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

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

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

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() 方法。

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

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(),该函数将在超时后运行要执行的代码。

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

// 使用箭头语法的匿名回调函数。
setTimeout(() => console.log("你好!"), 1000)
// 这等同于使用function关键字
setTimeout(function() { console.log("你好!") }, 1000)

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

// 应该能用,但不能用
setTimeout(console.log, 1000, "你好")

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

// 应该没用,但确实有用
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() 函数:

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() 时指定增加的超时时间。

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

setTimeout(() => console.log(1), 1000)
setTimeout(() => console.log(2), 2000)
setTimeout(() => console.log(3), 3000)

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

它会循环运行吗?

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

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

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()

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

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休眠或等待的资料请关注Devmax其它相关文章!

如何使JavaScript休眠或等待的更多相关文章

  1. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  2. HTML5数字输入仅接受整数的实现代码

    这篇文章主要介绍了HTML5数字输入仅接受整数的实现代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. amaze ui 的使用详细教程

    这篇文章主要介绍了amaze ui 的使用详细教程,本文通过多种方法给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  4. html5简介_动力节点Java学院整理

    这篇文章主要介绍了html5简介,用于指定构建网页的元素,这些元素中的大多数都用于描述网页内容,有兴趣的可以了解一下

  5. ios 8 Homescreen webapp,关闭和打开iPad停止javascript

    我有一个适用于iPad的全屏HTML5网络应用程序,并且刚刚安装了IOS8来试用它,它一切正常,直到你关闭并重新启动iPad.一旦web应用程序重新启动javascript就会停止并加载新页面不会重新启动它.在iPad上的Safari中打开同一页面时,关闭和打开iPad会继续按预期工作.其他人注意到了这个或想出了一个解决方案吗?解决方法这似乎是我在iOS8.1.1更新中解决的.

  6. iOS 6 javascript与object.defineProperty的间歇性问题

    当访问使用较新的Object.defineProperty语法定义属性的对象的属性时,有没有其他人注意到新iOS6javascript引擎中的间歇性错误/问题?https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty我正在看到javascript失败的情况,说

  7. ios – 如何使用JSExport导出内部类的方法

    解决方法似乎没有办法将内部类函数导出到javascript.我将内部类移出并创建了独立的类,它起作用了.

  8. 静音iOS推送通知与React Native应用程序在后台

    我有一个ReactNative应用程序,我试图获得一个发送到JavaScript处理程序的静默iOS推送通知.我看到的行为是AppDelegate中的didReceiveRemoteNotification函数被调用,但是我的JavaScript中的处理程序不会被调用,除非应用程序在前台,或者最近才被关闭.我很困惑的事情显然是应用程序正在被唤醒,并且它的didReceiveRemoteNotifi

  9. ios – 内存泄漏与UIWebView和Javascript

    清楚地包含一个Javascript文件到我的HTML是使UIWebView泄漏内存.当我重复使用相同的UIWebView对象时,或者每当我有内容实例化一个新的漏洞时,会出现泄漏的事实,导致我认为必须有一些JavaScript文件被loadHTMLString处理,导致泄漏.有人知道如何解决这个问题吗?

  10. iOS应用程序的UI自动化测试如何与乐器和Javascript

    从WWDC2010视频会议中了解iOS应用程序的自动化UI测试,但没有实践.从代码项目project,我们可以有一个例子.这个问题在这里听到有涉及这个的人.任何限制?解决方法我建议从AlexWollmer开始使用thisblogpost.他创建了一个非常有用的JavaScript库:tuneup_jswithtest()函数,它允许测试分离和有用的帮助者以及为自动化仪器编写测试的断言.

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部