【面试题】写一个睡眠函数

题目要求

请你编写一个异步函数,它接收一个正整数参数 millis ,并休眠 millis 毫秒。要求此函数可以解析任何值。

示例 1:

输入:millis = 100

输出:100

解释:

在 100ms 后此异步函数执行完时返回一个 Promise 对象

let t = Date.now();

sleep(100).then(() => {

console.log(Date.now() - t); // 100

});

示例 2:

输入:millis = 200

输出:200

解释:在 200ms 后函数执行完时返回一个 Promise 对象

方法 1:使用 Promises 和 setTimeout 的异步编程

概述

在 JavaScript 中,通常使用承诺来处理异步操作。承诺表示一个值,该值可能还不可用,但将在将来的某个时候解决(或在出错的情况下拒绝)。要在 JavaScript 中模拟延迟或"休眠",我们可以使用 setTimeout 函数,该函数将一个函数调度为在一段时间后运行。

该任务要求我们创建一个休眠指定毫秒的异步函数。要实现这一点,我们可以将 promises 与 setTimeout 结合起来。我们将返回在指定延迟后解决的承诺。

算法步骤

  1. 定义一个名为 sleep(millis) 的异步函数。此函数在解析之前将暂停执行 millis 毫秒。
  2. 在该函数内部,构造一个新的 promise 对象。这个 promise 对象的 executor 函数是我们将合并延迟的地方。
  3. 在 executor 函数中,使用 setTimeout 方法。setTimeout 是由主机环境(Web 浏览器、Node.js等)提供的方法。它在指定的延迟后执行提供的函数或代码段。
  4. 将 setTimeout 的延迟设置为 millis 毫秒。延迟后执行的代码将是 promise 的 resolve 方法。
  5. 当调用 resolve 方法时,它会将承诺标记为已实现,从而允许执行任何附加的 .then 处理程序。

实现

javascript 复制代码
async function sleep(millis) {
  return new Promise(resolve => {
    setTimeout(resolve, millis);
  });
}

在此实现中,sleep 函数是返回 promise 的异步函数。promise 的 executor 函数使用 setTimeout 在 millis 毫秒后解析 promise。请注意,我们实际上并不需要将睡眠功能设置为异步,因为我们直接返回一个 promise,但将其标记为 async 并不会有什么坏处。

你可以像这样在你的代码中使用 sleep 函数:

javascript 复制代码
let t = Date.now();
sleep(100).then(() => {
    console.log(Date.now() - t); // 大约 100
});

在这种用法中,我们记录当前时间,调用 sleep 函数,然后记录 promise 解析时经过的时间。运行时间应该大致等于 sleep 的输入,这表明函数确实已经"休眠"了指定的时间量。

请注意,使用 return new Promise() 或 return await new Promise() 都会在异步函数中产生相同的结果,如概述部分所述。

此外,使用 try {} catch(){} 也是异步编程中的一种常见做法,因为它允许您处理可能引发的任何潜在异常。在下面的解决方案中,如果在 setTimeout 函数的执行过程中出现错误,则 promise 被拒绝,并抛出错误:

javascript 复制代码
async function sleep(millis) {
  return new Promise((res,rej) => {
    try {
      setTimeout(() => res(5), millis)
    } catch(err) {
      rej(err)
    }
  })
}

方法 2:使用 Promises 和 setTimeout 不带返回的异步编程

这种方法与第一种方法类似,但略有不同:对于这个问题,您不需要显式返回任何内容。这也使以下代码成为有效的解决方案。此版本的 sleep 函数不返回任何内容(或者更准确地说,它返回 undefined),因为没有返回语句。但由于问题陈述说,"它可以求解任何值",这是完全可以接受的。这也是一个非常有效的俏皮话。

实现

javascript 复制代码
async function sleep(milliseconds) {
	await new Promise(res => setTimeout(res, milliseconds)); 
}
相关推荐
WeiXiao_Hyy31 分钟前
成为 Top 1% 的工程师
java·开发语言·javascript·经验分享·后端
吃杠碰小鸡1 小时前
高中数学-数列-导数证明
前端·数学·算法
kingwebo'sZone1 小时前
C#使用Aspose.Words把 word转成图片
前端·c#·word
xjt_09011 小时前
基于 Vue 3 构建企业级 Web Components 组件库
前端·javascript·vue.js
我是伪码农1 小时前
Vue 2.3
前端·javascript·vue.js
夜郎king2 小时前
HTML5 SVG 实现日出日落动画与实时天气可视化
前端·html5·svg 日出日落
辰风沐阳2 小时前
JavaScript 的宏任务和微任务
javascript
夏幻灵3 小时前
HTML5里最常用的十大标签
前端·html·html5
冰暮流星3 小时前
javascript之二重循环练习
开发语言·javascript·数据库
Mr Xu_3 小时前
Vue 3 中 watch 的使用详解:监听响应式数据变化的利器
前端·javascript·vue.js