第九节 高频代码题-实现Sleep函数(异步控制)

⚙️ 一、基础实现方案

1. ​​Promise + setTimeout 标准实现​​
复制代码
function sleep(ms: number): Promise<void> {
  return new Promise(resolve => setTimeout(resolve, ms));
}

​​原理​​:

  • 返回一个 Promise 对象,在指定毫秒(ms)后调用 resolve 结束等待。
  • 通过 setTimeout 实现异步调度,避免阻塞主线程。
2. ​​使用示例(async/await)​​
复制代码
async function demo() {
  console.log("开始等待");
  await sleep(2000); // 暂停 2 秒
  console.log("等待结束");
}
demo();

​​输出​​:

复制代码
开始等待
(2秒后)
等待结束

🚀 二、工程化增强方案

1. ​​支持返回值传递​​

通过泛型扩展 sleep 功能,实现延迟后返回数据:

复制代码
function sleep<T>(ms: number, value?: T): Promise<T | void> {
  return new Promise(resolve => 
    setTimeout(() => resolve(value), ms)
  );
}

// 使用:延迟后返回字符串
async function fetchWithDelay() {
  const data = await sleep(1000, "Hello, World!");
  console.log(data); // 输出 "Hello, World!"
}
2. ​​集成错误处理​​

支持延迟中抛出异常:

复制代码
function sleep(ms: number, shouldReject = false): Promise<void> {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      shouldReject ? reject(new Error("Sleep interrupted")) : resolve();
    }, ms);
  });
}

// 使用:模拟失败场景
async function riskyOperation() {
  try {
    await sleep(1000, true);
  } catch (error) {
    console.error(error.message); // 输出 "Sleep interrupted"
  }
}

⚠️ 三、关键注意事项

  1. ​​非阻塞特性​ ​
    sleep 通过事件循环实现延迟,​​不会阻塞同步代码​​:

    复制代码
    console.log("Start");
    sleep(2000).then(() => console.log("Delayed"));
    console.log("End");
    // 输出:Start → End →(2秒后)→ Delayed
  2. ​​禁止同步滥用​ ​

    在同步函数中调用 await sleep() 会导致整个函数暂停,但若在非 async 函数中使用会报错:

    复制代码
    function syncFunction() {
      await sleep(1000); // ❌ 语法错误:await 仅在 async 函数中有效
    }
  3. ​​替代方案对比​​

    ​​方法​​ ​​适用场景​​ ​​缺点​​
    setTimeout 简单回调场景 嵌套易导致回调地狱
    Promise + sleep 现代异步流程(推荐) 需配合 async/await
    第三方库(如 bluebird) 复杂任务调度 增加依赖体积

💡 四、典型应用场景

  1. ​​接口轮询控制​​

    复制代码
    async function pollAPI() {
      while (true) {
        const data = await fetchData();
        if (data.status === "ready") break;
        await sleep(5000); // 每 5 秒轮询一次
      }
    }
  2. ​​用户操作防抖​​

    复制代码
    let searchTimer: number;
    function onSearchInput(query: string) {
      clearTimeout(searchTimer);
      searchTimer = setTimeout(async () => {
        await sleep(300); // 延迟 300ms 后执行搜索
        runSearch(query);
      }, 300);
    }
  3. ​​动画序列控制​​

    复制代码
    async function playAnimations() {
      animateElement1();
      await sleep(1000);
      animateElement2();
      await sleep(500);
      animateElement3();
    }

🛠️ 五、扩展:Node.js 环境优化

在 Node.js 中可复用 setTimeout,或使用 setImmediate 实现微秒级延迟:

复制代码
import { setTimeout } from "timers/promises"; // Node.js 16+

async function nodeSleep(ms: number) {
  await setTimeout(ms);
}

​​最佳实践总结​​:

  • ✅ ​优先 Promise 方案​:保持代码简洁与现代异步规范兼容;
  • ⚠️ ​避免同步思维​ :理解事件循环机制,禁止在非 async 函数中调用 await sleep();
  • 🚀 ​场景驱动设计​:根据轮询、动画、防抖等需求选择合理延迟时长。
相关推荐
变与不变8068 分钟前
js同步和异步难点重点详解
开发语言·javascript·ecmascript
特立独行的猫a20 分钟前
用仓颉写一个 Tauri:IPC 的每次往返实现原理(web层到仓颉层的触发过程)
前端·ui·harmonyos·tauri·鸿蒙·仓颉
Dovis(誓平步青云)20 分钟前
多个链接不等于多份证据,新闻核验看板怎样合并来源
java·服务器·前端·javascript·人工智能·pdf·电脑
骑着蜗牛撵大象32735 分钟前
Qt 事件机制详解:从 QEvent 派生类到事件过滤器的全景指南
前端·python
qq_2518364571 小时前
理发管理系统 —— 会员模块
开发语言·前端·python·flask
Dovis(誓平步青云)1 小时前
几个方案来回选不定?做一个随时切换的候选推荐页
android·java·服务器·开发语言·javascript·数据库·智能化
Frag0ut1 小时前
2027 年浏览器展望:Chrome 与 Edge 的 AI 智能体进化方向
前端·人工智能·chrome·edge·浏览器·新功能
计算机魔术师2 小时前
从AI绘图鼻祖到音乐版权破局者,Stability AI如何被三大唱片巨头「收编」
前端
奕鼎竜瑆2 小时前
Chrome 插件开发实战指南:从入门到发布
前端·chrome
广州华水科技2 小时前
水库北斗GNSS变形监测系统及单北斗形变监测一体机应用解析
前端