极客时间返利平台,你可以在上边通过山月的链接购买课程,并添加我的微信 (shanyue94) 领取返现。
每天晚上九点 B站讲解前端工程化直播,并解答相关问题。

# JS 如何实现一个 sleep/delay 函数

更多描述

sleep 函数实现较为简单,也常作为对 Promise 的代码考察。在日常工作中,特别是 Node 写脚本时,常用它控制频率。

实现一个 sleep 函数格式如下:

type sleep = (s: number) => Promise<void>;

追问:

实现一个 delay 函数格式如下,在 N 毫秒之后执行函数,并以函数结果作为返回值

function delay(func, seconds, ...args) {}

// 在 3s 之后返回 hello, world
await delay((str) => str, 3000, "hello, world");

// 在 3s 之后返回 hello, world,第一个函数可返回 promise
await delay((str) => Promise.resolve(str), 3000, "hello, world");

Issue

欢迎在 Gtihub Issue 中回答此问题: Issue 442 (opens new window)

Author

回答者: yuuk (opens new window)

function delay(time) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve();
    }, time);
  });
}
const sleep = (t = 0) => new Promise((resolve) => setTimeout(resolve, t));
function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if (new Date().getTime() - start > milliseconds) {
      break;
    }
  }
}

from: kurento-utils-js (opens new window)

sleep 函数既是面试中常问到的一道代码题,也是日常工作,特别是测试中常用的一个工具函数。

实现起来较为简单,一行即可实现,代码如下

const sleep = (seconds) =>
  new Promise((resolve) => setTimeout(resolve, seconds));

实现一个 delay 稍微复杂点,代码见 【Q435】JS 如何实现一个 sleep/delay 函数 (opens new window)

function delay(func, seconds, ...args) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      Promise.resolve(func(...args))
        .then(resolve)
        .catch(reject);
    }, seconds);
  });
}

使用代码测试:

console.log(new Date());
delay(
  (str) => {
    console.log(new Date());
    return str;
  },
  3000,
  "shanyue"
).then((o) => console.log(o));
type resolving<P = any> = (res: P) => void;

function delay<P extends any[], T extends (...args: P) => any = () => null>(
  func: T,
  seconds: number = 0,
  ...args: P
): Promise<ReturnType<T>> {
  let _resolve: resolving<ReturnType<T>>;
  let _reject: resolving;
  setTimeout(() => {
    try {
      _resolve(func(...args));
    } catch (e) {
      _reject(e);
    }
  }, seconds);
  return new Promise((resolve, reject) => {
    _resolve = resolve;
    _reject = reject;
  });
}

@heretic-G 如果写成 TS 的话,如何标记 type

async function delay(func, second, ...args) {
  return await new Promise((resolve) => {
    setTimeout(() => {
      resolve(func(...args));
    }, second);
  });
}

delay((str) => str, 3000, "Hello world").then((res) => {
  console.log(res);
});

@HengistChan 如果 return promise 的话,应该可以不需要加 async/await

Last Updated: 11/27/2021, 10:11:48 AM