函数睡眠
伪命题,JavaScript 引擎线程无法挂起,通过异步实现类似 sleep 的效果。
代码实现
回调函数实现
const sleep = (cb, time) => setTimeout(cb, time);
sleep(() => {
  console.log('Hello world!');
}, 1000);
Promise 实现
function sleep(time) {
  return function() {
    return new Promise(function(resolve, reject) {
      setTimeout(resolve, time);
    });
  };
}
const promise = new Promise(function(resolve) {
  console.log('do something');
  resolve();
})
  .then(sleep(2000))
  .then(function() {
    console.log('after sleep 2000');
  });
- 优点:这种方式实际上是用了 setTimeout,没有形成进程阻塞,不会造成性能和负载问题
- 缺点:虽然不像 callback套那么多层,但仍不怎么美观,而且当我们需要在某过程中需要停止执行(或者在中途返回了错误的值),还必须得层层判断后跳出,非常麻烦,而且这种异步并不是那么彻底,还是看起来别扭
Generator 实现
function* sleep(time) {
  yield new Promise(function(resolve, reject) {
    setTimeout(resolve, time);
  });
}
sleep(1000)
  .next()
  .value.then(() => {
    console.log('Hello world!');
  });
- 优点:同 Promise 优点,另外代码就变得非常简单干净,没有 then那么生硬和恶心
- 缺点:但不足也很明显,就是每次都要执行 next显得很麻烦,虽然有co(第三方包)可以解决,但就多包了一层不好看,错误也必须按co的逻辑来处理不爽
Async/Await 实现
function sleep(time) {
  return new Promise(function(resolve) {
    setTimeout(resolve, time);
  });
}
async function test() {
  const res = await sleep(1000);
  console.log('Hello world!');
  return res;
}
// 延迟 1000ms 输出 "Hello world!"
- 优点:同 Promise 和 Generator 的优点。Async/Await 可以看座是 Generator 的语法糖,Async 和 Await 相较于 *和yield更加语义,另外各个函数都是扁平的,不会产生多余的嵌套,代码更加清爽易读。
- 缺点:ES7 语法存在兼容性问题,有 Babel 一切兼容性都不是问题
使用 node-sleep
const sleep = requir('node-sleep');
const sec = 10;
sleep.sleep(sec);
// Sleep for sec seconds
sleep.msleep(sec);
// Sleep for sec milliseconds
sleep.usleep(sec);
// Sleep for sec microseconds(1 second is 1000000 microseconds)