时间:2021-05-28
本文实例讲述了javascript 使用sleep函数的常见方法。分享给大家供大家参考,具体如下:
一.什么是sleep函数?
花一点时间来聊一下sleep函数,首先什么是sleep函数?
sleep是一种函数,他的作用是使程序暂停指定的时间,起到延时的效果。
例如:
console.log('1');sleep(5000);console.log('2');控制台输出数字1后会间隔5秒后输出数字2
当然上面的代码是不能执行的,因为js中是没有sleep方法的。
所以这一篇文章主要介绍几种在js中实现sleep的方式。
二.为什么使用sleep?
看到这里有人会问了,为什么要使用sleep,上面的例子我可以使用setTimeout来实现啊?
因为setTimeout是通过回调函数来实现定时任务的,所以在多任务的场景下就会出现回调嵌套:
console.time('runTime:');setTimeout(function(){ console.log('1') setTimeout(function(){ console.log('2'); setTimeout(function(){ console.log('3'); console.timeEnd('runTime:'); }, 2000); }, 3000);}, 2000);// 1// 2// 3// runTime:: 7013.104ms上面的方式存在回调嵌套的问题,我们希望有一个优雅的方式来实现上面的例子:
sleep(2000);console.log('1');sleep(3000);console.log('2');sleep(2000);console.log('3');...三.实现sleep
接下来我们就分别用几种不同的方法来实现下sleep方法
1.基于Date实现
通过死循环来阻止代码执行,同时不停比对是否超时。
function sleep(time){ var timeStamp = new Date().getTime(); var endTime = timeStamp + time; while(true){ if (new Date().getTime() > endTime){ return; } }}console.time('runTime:');sleep(2000);console.log('1');sleep(3000);console.log('2');sleep(2000);console.log('3');console.timeEnd('runTime:');// 1// 2// 3// runTime:: 7004.301ms缺点:
以上的代码不会让线程休眠,而是通过高负荷计算使cpu无暇处理其他任务。
这样做的缺点是在sleep的过程中其他所有的任务都会被暂停,包括dom的渲染。
所以sleep的过程中程序会处于假死状态,并不会去执行其他任务
2.基于Promise的sleep
为了解决ajax的回调嵌套问题,在jQuery1.8之后支持了Promise。但是单纯的Promise只是将之前的纵向嵌套改为了横向嵌套,
最终结果是下面的代码:
function sleep(time){ return new Promise(function(resolve){ setTimeout(resolve, time); });}console.time('runTime:');console.log('1');sleep(1000).then(function(){ console.log('2'); sleep(2000).then(function(){ console.log('3'); console.timeEnd('runTime:'); });});console.log('a');// 1// a// 2// 3// runTime:: 3013.476ms这其实和之前的setTimeout嵌套没什么区别,也很难看。
我们再次进行优化,使用ES6的Generator函数来改写上面的例子
3.基于Generator函数的sleep
我们对sleep的执行使用Generator函数来执行,并且搭配co来进行自执行。
看代码:
var co = require('co'); function sleep(time){ return new Promise(function(resolve){ setTimeout(resolve, time); });} var run = function* (){ console.time('runTime:'); console.log('1'); yield sleep(2000); console.log('2'); yield sleep(1000); console.log('3'); console.timeEnd('runTime:');} co(run);console.log('a');// 1// a// 2// 3// runTime:: 3004.935ms可以看到整体的代码看起来不存在嵌套的关系,还是比较舒服的。
并且执行过程不会发生假死情况,不会阻塞其他任务的执行。
但是多了一个co执行器的引用,所以还是有瑕疵。
当然这不是最终版,因为ES7为我们带来了新的解决方案。
4.基于async函数的sleep
ES7新增了async函数,async函数最大的特点就是自带执行器,所以我们可以不借助co来实现sleep了
看代码:
function sleep(time){ return new Promise((resolve) => setTimeout(resolve, time));} async function run(){ console.time('runTime:'); console.log('1'); await sleep(2000); console.log('2'); await sleep(1000); console.log('3'); console.timeEnd('runTime:');} run();console.log('a'); // 1// a// 2// 3// runTime:: 3009.984ms效果和之前的一样。
5.使用child_process(子进程)实现sleep函数
前面介绍了几种比较简单的sleep实现,接下来看一个比较难的实现。
原理是将sleep放在子进程中执行,不会影响其他进程,看代码:
var childProcess = require('child_process');var nodeBin = process.argv[0]; function sleep(time) { childProcess.execFileSync(nodeBin, ['-e', 'setTimeout(function() {}, ' + time + ');']); // childProcess.spawnSync(nodeBin, ['-e', 'setTimeout(function() {}, ' + time + ');']);} console.time('runTime:');console.log('1');sleep(1000);console.log('2');sleep(2000);console.log('3');console.timeEnd('runTime:'); // 1// 2// 3// runTime:: 3579.093ms以上代码,是通过childProcess对象的execFileSync或者spawnSync创建一个同步进程,
在同步进程中执行定时器,定时器执行完毕后回收进程,程序继续执行。
6.使用npm sleep包
前面的内容都是我们自己实现的,其实npm上已经有很多相关的js包了。
我们来看看他们是怎么实现的,sleep
var sleep = require('sleep'); console.log('1');console.time('runTime:');sleep.sleep(2); //休眠2秒钟console.log('2');sleep.msleep(1000); //休眠1000毫秒console.log('3');sleep.usleep(1000000) //休眠1000000微秒 = 1秒console.log('4');console.timeEnd('runTime:'); // 1// 2// 3// 4// runTime:: 4014.455ms很强有没有,sleep包是C++编写,然后扩展到Node来实现sleep函数
也是一个不错的选择。
以上就是sleep的六种简单实现。欢迎大家指出问题,我们一起进步。
感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.jb51.net/code/HtmlJsRun测试上述代码运行效果。
更多关于JavaScript相关内容可查看本站专题:《JavaScript常用函数技巧汇总》、《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》及《JavaScript数学运算用法总结》
希望本文所述对大家JavaScript程序设计有所帮助。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本文实例讲述了javascript操作元素的常见方法。分享给大家供大家参考,具体如下:获取元素方法一可以使用内置对象document上的getElementBy
COM组件中调用JavaScript函数详解及实例要求是很简单的,即有COM组件A在IE中运行,使用JavaScript(JS)调用A的方法longCalc()
本文实例讲述了JavaScript闭包与作用域链。分享给大家供大家参考,具体如下:闭包定义闭包指的是有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式,
Numba是Python的即时编译器,在使用NumPy数组和函数以及循环的代码上效果最佳。使用Numba的最常见方法是通过其装饰器集合,这些装饰器可应用于您的函
详解Java中的sleep()和wait()的区别对于sleep()方法,我们首先要知道该方法是属于Thread类中的。而wait()方法,则是属于Object