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

一.什么是sleep函数?

sleep是一种函数,他的作用是使程序暂停指定的时间,起到延时的效果。javascript 好像诶呦提供 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方法:

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

单纯的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执行器的引用,所以还是有瑕疵。

4、基于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

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

文章链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: