最近研究Node.js应用的稳定性和性能优化,发现测试时会用到故意延迟或卡顿的场景。度娘搜了一下有不少实现sleep的方式,顺便总结一下,分享给各位看官。

死循环

1
2
3
4
5
6
7
function sleep(sleepTime) {
for(var start = +new Date; +new Date - start <= sleepTime;) {};
}
var t1 = +new Date();
sleep(3000);
var t2 = +new Date();
console.log(t2 - t1);

这是最简单粗暴的实现,确实sleep了,也确实卡死了,CPU会飙升,无论你的服务器CPU有多么Niubility。

async

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var async = require('asyncawait/async');
var await = require('asyncawait/await');

function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}

(async(
function () {
var t1 = +new Date();
await(sleep(3000));
var t2 = +new Date();
console.log(t2 - t1);
}
))();

缺陷是程序需要在async域里执行。等ES7出来后会有原生的await/async可用,不用引入asyncawait模块了。
优点是,这种方式实际上是用了setTimeout,没有形成进程阻塞,不会造成性能和负载问题。

generator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var co = require('co');

function sleep(milliSeconds) {
return function (done) {
setTimeout(done, milliSeconds);
}
};

co(function*() {
var t1 = +new Date();
yield sleep(3000);
var t2 = +new Date();
console.log(t2 - t1);
});

目前generator在开发中应用的越来越多,尤其是koa在更多的业务中使用之后。缺点和async一样,必须在generator的域里才可使用。优点和上例相同。

addon

这里有C++实现的模块:https://github.com/ErikDubbelboer/node-sleep

  • sleep.sleep(n): sleep for n seconds
  • sleep.msleep(n): sleep for n miliseconds
  • sleep.usleep(n): sleep for n microseconds (1 second is 1000000 microseconds)
    能够实现更加精细的时间精确度。缺点需要安装这个模块,^_^,这也许算不上什么缺点。

总结

上面4种实现方法,各有优略表现最好的是用C++实现的模块,最简单的实现是死循环,对于不同的业务和应用场景,就看大家喜欢哪种方式了。

参考

https://www.zhihu.com/question/31636244
http://www.zhouhua.info/2015/03/04/sleep/
https://github.com/ErikDubbelboer/node-sleep

注意:本站博文均系原创,欢迎转载,请注明出处和原网址