您现在的位置是:首页 > 技术教程 正文

JavaScript中实现sleep睡眠函数的几种简单方法

admin 阅读: 2024-03-31
后台-插件-广告管理-内容页头部广告(手机)

目录

一.什么是sleep函数?

二.为什么使用sleep?

三.实现sleep


一.什么是sleep函数?

sleep是一种函数,他的作用是使程序暂停指定的时间,起到延时的效果。

官方介绍:sleep是一种函数,作用是延时,程序暂停若干时间,在执行时要抛出一个中断异常,必须对其进行捕获并处理才可以使用这个函数。

例如:

  1. console.log('1');
  2. sleep(2000);
  3. console.log('2');

控制台输出数字1后 会间隔2秒后输出数字2

当然上面的代码是不能执行的,因为js中是没有sleep方法的。

所以这一篇文章主要介绍几种在js中实现sleep的方式。

二.为什么使用sleep?

看到这里有人会问了,为什么要使用sleep,上面的例子我可以使用setTimeout来实现啊?

因为setTimeout是通过回调函数来实现定时任务的,所以在多任务的场景下就会出现回调嵌套:

  1. console.time('runTime:');
  2. setTimeout(() => {
  3. console.log('1');
  4. setTimeout(() => {
  5. console.log('2')
  6. setTimeout(() => {
  7. console.log('3')
  8. console.timeEnd('runTime:');
  9. }, 2000);
  10. }, 3000);
  11. }, 2000);
  12. //结果:
  13. //1
  14. //2
  15. //3
  16. //runTime:: 7017.87890625 ms

上面的方式存在回调嵌套的问题,我们希望可以利用sleep函数更方便优雅地实现上面的例子。

三.实现sleep

接下来我们就分别用几种不同的方法来实现下sleep方法:

  1. 基于Date实现

    通过死循环来阻止代码执行,同时不停比对是否超时。

    1. function sleep(time){
    2. var timeStamp = new Date().getTime();
    3. var endTime = timeStamp + time;
    4. while(true){
    5. if (new Date().getTime() > endTime){
    6. return;
    7. }
    8. }
    9. }
    10. console.time('runTime:');
    11. sleep(2000);
    12. console.log('1');
    13. sleep(3000);
    14. console.log('2');
    15. sleep(2000);
    16. console.log('3');
    17. console.timeEnd('runTime:');
    18. // 1
    19. // 2
    20. // 3
    21. // runTime:: 7004.301ms

    缺点:

    以上的代码不会让线程休眠,而是通过高负荷计算使cpu无暇处理其他任务。

    这样做的缺点是在sleep的过程中其他所有的任务都会被暂停,包括dom的渲染。

    所以sleep的过程中程序会处于假死状态,并不会去执行其他任务

  2. 基于Promise的sleep

    单纯的Promise只是将之前的纵向嵌套改为了横向嵌套:

    1. function sleep(time){
    2. return new Promise(function(resolve){
    3. setTimeout(resolve, time);
    4. });
    5. }
    6. console.time('runTime:');
    7. console.log('1');
    8. sleep(1000).then(function(){
    9. console.log('2');
    10. sleep(2000).then(function(){
    11. console.log('3');
    12. console.timeEnd('runTime:');
    13. });
    14. });
    15. console.log('a');
    16. // 1
    17. // a
    18. // 2
    19. // 3
    20. // runTime:: 3013.476ms

    这其实和之前的setTimeout嵌套没什么区别,也很难看。

    我们再次进行优化,使用ES6的Generator函数来改写上面的例子

  3. 基于Generator函数的sleep

    我们对sleep的执行使用Generator函数来执行,并且搭配co来进行自执行。

    1. var co = require('co');
    2. function sleep(time){
    3. return new Promise(function(resolve){
    4. setTimeout(resolve, time);
    5. });
    6. }
    7. var run = function* (){
    8. console.time('runTime:');
    9. console.log('1');
    10. yield sleep(2000);
    11. console.log('2');
    12. yield sleep(1000);
    13. console.log('3');
    14. console.timeEnd('runTime:');
    15. }
    16. co(run);
    17. console.log('a');
    18. // 1
    19. // a
    20. // 2
    21. // 3
    22. // runTime:: 3004.935ms

    可以看到整体的代码看起来不存在嵌套的关系,并且执行过程不会发生假死情况,不会阻塞其他任务的执行。

    但是多了一个co执行器的引用,所以还是有瑕疵。

  4. 基于async函数的sleep

    async函数最大的特点就是自带执行器,所以我们可以不借助co来实现sleep了

    1. function sleep(time){
    2. return new Promise((resolve) => setTimeout(resolve, time));
    3. }
    4. async function run(){
    5. console.time('runTime:');
    6. console.log('1');
    7. await sleep(2000);
    8. console.log('2');
    9. await sleep(1000);
    10. console.log('3');
    11. console.timeEnd('runTime:');
    12. }
    13. run();
    14. console.log('a');
    15. // 1
    16. // a
    17. // 2
    18. // 3
    19. // runTime:: 3009.984ms

标签:
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

在线投稿:投稿 站长QQ:1888636

后台-插件-广告管理-内容页尾部广告(手机)
关注我们

扫一扫关注我们,了解最新精彩内容

搜索
排行榜