JavaScript 实现 sleep 函数的 4 种方式

2,564 阅读2分钟

sleep 函数可以使程序暂停执行,等到指定的时间后再重新执行,能起到延时的效果。在很多的编程语言里都提供了 Sleep 函数,如 C/C++ 中的 Sleep() 函数,linux 中的 sleep() 函数。在 JavaScript 语言中,原生提供了 setTimeout() 方法来实现一段时间后执行某个任务,但这种写法需要提供回调函数,写法上很不优雅。

回调函数 方式

function sleep(callback, time) {
    if (typeof callback === 'function') {
    setTimeout(callback, time)
  }
}

sleep(function(){console.log("1")}, 1000)

setTimeout 是通过回调函数来实现定时任务,当在多个异步操作需要逐步完成场景下,例如相继获取多个 API 的结果,就会出现回调嵌套的情况,而且当异步的操作越来越多时,回调的嵌套会越来越深,代码的执行顺序会非常不直观,也不利于维护。

// 回调嵌套
setTimeout(function(){
 console.log('1')
 setTimeout(function(){
 console.log('2');
 setTimeout(function(){
  console.log('3');
 }, 2000);
 }, 3000);
}, 2000);
// 1
// 2
// 3

接下来,我们用更优雅的方式实现 sleep 函数,从而解决回调嵌套的问题。

Promise 方式

Promise 是 ES6 提供的一种异步编程解决方案,它将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供统一的接口,使得控制异步操作更加容易

const sleep = time => {
    return new Promise(resolve => setTimeout(resolve, time));
}

sleep(1000).then(() => console.log("1"))

Generator 方式

Generator 函数是 ES6 提供的一种异步编程解决方案,返回一个遍历器对象,需要调用next方法,或者用co模块,才能真正执行,得到最后结果

function* sleepGenerator(time){
    yield new Promise(resolve => setTimeout(resolve, time));
}
const sleep = time => sleepGenerator(time).next().value;

sleep(1000).then(() => console.log('1'))

await/async 方式

async 函数就是 Generator 函数的语法糖,它内置了自动执行器,与普通函数的执行一模一样。

async function sleep(time) {
    await new Promise(resoleve => setTimeout(resoleve, time));
}

sleep(1000).then(() => console.log('1'))