第九节 高频代码题-实现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()
  • 🚀 ​场景驱动设计​:根据轮询、动画、防抖等需求选择合理延迟时长。
相关推荐
Moonbeam Community1 分钟前
应用爆发,DeFi先行
javascript·ide·web3·区块链·polkadot
2301_796512524 分钟前
使用状态管理、持久化存储或者利用现有的库来辅助React Native鸿蒙跨平台开发开发一个允许用户撤销删除的操作
javascript·react native·react.js
全马必破三9 分钟前
浏览器原理知识点总结
前端·浏览器
零Suger10 分钟前
React 组件通信
前端·react.js·前端框架
LYFlied14 分钟前
【每日算法】 LeetCode 394. 字符串解码
前端·数据结构·算法·leetcode·面试·职场和发展
前端不太难21 分钟前
RN Navigation vs Vue Router 的架构对比
javascript·vue.js·架构
硕子鸽24 分钟前
UniApp + Dify 实战:详解 SSE 流式响应的解析与前端渲染
前端·uni-app·dify
lxh011325 分钟前
复原IP地址
前端·数据结构·算法
小白学大数据26 分钟前
Python 爬虫如何分析并模拟 JS 动态请求
开发语言·javascript·爬虫·python