JavaScript中实现sleep睡眠函数的几种简单方法
后台-插件-广告管理-内容页头部广告(手机) |
目录
一.什么是sleep函数?
二.为什么使用sleep?
三.实现sleep
一.什么是sleep函数?
sleep是一种函数,他的作用是使程序暂停指定的时间,起到延时的效果。
官方介绍:sleep是一种函数,作用是延时,程序暂停若干时间,在执行时要抛出一个中断异常,必须对其进行捕获并处理才可以使用这个函数。
例如:
- console.log('1');
- sleep(2000);
- console.log('2');
控制台输出数字1后 会间隔2秒后输出数字2
当然上面的代码是不能执行的,因为js中是没有sleep方法的。
所以这一篇文章主要介绍几种在js中实现sleep的方式。
二.为什么使用sleep?
看到这里有人会问了,为什么要使用sleep,上面的例子我可以使用setTimeout来实现啊?
因为setTimeout是通过回调函数来实现定时任务的,所以在多任务的场景下就会出现回调嵌套:
- console.time('runTime:');
- setTimeout(() => {
- console.log('1');
- setTimeout(() => {
- console.log('2')
- setTimeout(() => {
- console.log('3')
- console.timeEnd('runTime:');
- }, 2000);
- }, 3000);
- }, 2000);
- //结果:
- //1
- //2
- //3
- //runTime:: 7017.87890625 ms
上面的方式存在回调嵌套的问题,我们希望可以利用sleep函数更方便优雅地实现上面的例子。
三.实现sleep
接下来我们就分别用几种不同的方法来实现下sleep方法:
-
基于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的过程中程序会处于假死状态,并不会去执行其他任务
-
基于Promise的sleep
单纯的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函数来改写上面的例子
-
基于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执行器的引用,所以还是有瑕疵。
-
基于async函数的sleep
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
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。
在线投稿:投稿 站长QQ:1888636
后台-插件-广告管理-内容页尾部广告(手机) |