领先的免费Web技术教程,涵盖HTML到ASP.NET

网站首页 > 知识剖析 正文

javascript中怎么实现sleep函数?(js sleep函数实现)

nixiaole 2024-11-17 00:23:37 知识剖析 24 ℃

什么是sleep函数,就是让程序暂停指定时间,起到延时的效果,这个功能在做爬虫的时候特别有用。例如:

console.log('1', new Date())
sleep(2000)
console.log('1', new Date())

当然这个实际是没法执行的,因为JavaScript中没有sleep函数。下面我们来几个方法实现之。

  • 使用setTimeout嵌套实现
console.time('runTime:');
setTimeout(function () {
    console.log('1', new Date())
    setTimeout(function () {
        console.log('2', new Date());
        setTimeout(function () {
            console.log('3', new Date());
            console.timeEnd('runTime:');
        }, 2000);
    }, 3000);
}, 2000);
// 输出如下:
// 1 2022-09-18T01:25:48.317Z
// 2 2022-09-18T01:25:51.333Z
// 3 2022-09-18T01:25:53.341Z
// runTime:: 7.038s

这段代码是不是看的很晕,嵌套的太麻烦了

  • 使用死循环
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', new Date());
sleep(3000);
console.log('2', new Date());
sleep(2000);
console.log('3', new Date());
console.timeEnd('runTime:');
// 输出如下
// 1 2022-09-18T01:29:19.529Z
// 2 2022-09-18T01:29:22.534Z
// 3 2022-09-18T01:29:24.536Z
// runTime:: 7.008s

这个方法因为有短期无限死循环,会让整个程序假死,页面也会假死,不具备实用价值

  • 基于Promise
function sleep(time) {
    return new Promise(function (resolve) {
        setTimeout(resolve, time);
    });
}
console.time('runTime:');
console.log('1', new Date());
sleep(1000).then(function () {
    console.log('2', new Date());
    sleep(2000).then(function () {
        console.log('3', new Date());
        console.timeEnd('runTime:');
    });
});
console.log('a', new Date());
// 输出如下:
// 1 2022-09-18T01:32:40.420Z
// a 2022-09-18T01:32:40.425Z
// 2 2022-09-18T01:32:41.439Z
// 3 2022-09-18T01:32:43.45
  • 基于async, promise 的sleep
// 还是这个看起来最简洁好用
function sleep(time) {
    return new Promise((resolve) => setTimeout(resolve, time));
}
async function run() {
    console.time('runTime:');
    console.log('1', new Date());
    await sleep(2000);
    console.log('2', new Date());
    await sleep(1000);
    console.log('3', new Date());
    console.timeEnd('runTime:');
}
run();
console.log('a', new Date());
// 输出如下:
// 1 2022-09-18T01:35:17.775Z
// a 2022-09-18T01:35:17.779Z
// 2 2022-09-18T01:35:19.790Z
// 3 2022-09-18T01:35:20.802Z
// runTime:: 3.027s
  • 使?child_process(?进程)实现sleep函数
var childProcess = require('child_process');
var nodeBin = process.argv[0];
function sleep(time) {
childProcess.execFileSync(nodeBin, ['-e', 'setTimeout(function() {}, ' + time + ');']); // spawnSync函数 也可以
// childProcess.spawnSync(nodeBin, ['-e', 'setTimeout(function() {}, ' + time + ');']);
}
console.time('runTime:');
console.log('1', new Date());
sleep(1000);
console.log('2', new Date());
sleep(2000);
console.log('3', new Date());
console.timeEnd('runTime:');
// 输出如下:
// 1 2022-09-18T01:37:50.387Z
// 2 2022-09-18T01:37:51.445Z
// 3 2022-09-18T01:37:53.500Z
// runTime:: 3.113s

以上代码,是通过childProcess对象的execFileSync或者spawnSync创建?个同步进程,在同步进程中执?定时器,定时器执?完毕后回收进程,程序继续执?。

  • 使用npm的sleep包
var sleep = require('sleep');
console.log('1', new Date());
console.time('runTime:');
sleep.sleep(2); //休眠2秒钟
console.log('2', new Date());
sleep.msleep(1000); //休眠1000毫秒
console.log('3', new Date());
sleep.usleep(1000000) //休眠1000000微秒 = 1秒
console.log('4', new Date());
console.timeEnd('runTime:');
// 输出如下:
// 1 2022-09-18T01:42:07.302Z
// 2 2022-09-18T01:42:09.311Z
// 3 2022-09-18T01:42:10.320Z
// 4 2022-09-18T01:42:11.334Z
// runTime:: 4.028s

这个sleep支持了好几种时间类型,很棒,但是缺点是它是使用c++编写,某些环境下需要安装其他依赖才能支持。比如在winserver 2008下就不能用了。

总结:多种方法,最简洁的还是 promise+ async 。

  • 关注老胡,分享更多简洁实用的技术

Tags:

最近发表
标签列表