当前位置: 首页 > news >正文

懒汉式——LazyMan(任务队列应用)

代码

/*** 懒汉式 LazyMan* @description* 注意:* 1. 在每次执行的任务里面调用next(任务按顺序执行),而不是添加任务后执行next(立即执行task,多个任务会同时触发)* 2. 使用setTimeout确保构造函数执行完再启动任务队列*/
class LazyMan {constructor(name) {this.name = name// 任务队列this.tasks = []const task = () => {console.log(`Hi I am ${name}`);this.next();}this.tasks.push(task)// 确保构造函数执行完再启动任务队列setTimeout(() => {this.next()}, 0)}// 启动一次任务队列(执行第一个任务)next() {const task = this.tasks.shift()if (task) task()}eat(food) {const task = () => {console.log(`Eat ${food}~`);this.next();}this.tasks.push(task)return this}sleep(seconds) {const task = () => {setTimeout(() => {console.log(`Wake up after ${seconds}s`);this.next();}, seconds * 1000)}this.tasks.push(task)return this}sleepFirst(seconds) {const task = () => {setTimeout(() => {console.log(`Wake up after ${seconds}s`);this.next();}, seconds * 1000)}this.tasks.unshift(task)return this}
}// new LazyMan("Hank").eat("dinner");
// Hi I am Hank
// Eat dinner~// new LazyMan("Hank").sleep(2).eat("dinner");
// Hi I am Hank
// (2秒后) Wake up after 2s
// Eat dinner~// new LazyMan("Hank").sleepFirst(2).eat("dinner");
// (2秒后) Wake up after 2s
// Hi I am Hank
// Eat dinner~

在每次执行的任务里面调用next,而不是添加任务后执行next

每次执行的任务里面调用 next,确保任务按顺序执行。

如果添加任务后就立刻执行next,会导致每一个加入的任务都立刻执行,违背了串行,类似于并行执行。

使用setTimeout确保构造函数执行完再启动任务队列

先看构造函数里如果 立刻调用 this.next() 会怎样

class LazyMan {constructor(name) {this.tasks = []const task = () => {console.log(`Hi I am ${name}`)this.next()}this.tasks.push(task)// ⚠️ 这里如果立刻调用 nextthis.next()}next() {const task = this.tasks.shift()if (task) task()}eat(food) {const task = () => {console.log(`Eat ${food}`)this.next()}this.tasks.push(task)return this}
}new LazyMan("Tom").eat("apple")

执行顺序

  1. new LazyMan("Tom") 执行构造函数。

    • tasks.push("Hi I am Tom")
    • 立刻 next() → 执行 “Hi I am Tom”
  2. 构造函数还没结束,已经执行掉第一个任务了。

  3. 接着调用 .eat("apple"),才把 Eat apple 放到队列里。

    • 但是此时队列已经空了(第一个任务执行完时队列已经没东西了)。
    • 所以 Eat apple 永远不会执行。

👉 结果:

Hi I am Tom

而不是期望的:

Hi I am Tom
Eat apple

这就是「来不及入队」的意思。


再看 setTimeout(..., 0) 的情况

class LazyMan {constructor(name) {this.tasks = []const task = () => {console.log(`Hi I am ${name}`)this.next()}this.tasks.push(task)// ✅ 延迟到构造函数执行完后才启动队列setTimeout(() => {this.next()}, 0)}next() {const task = this.tasks.shift()if (task) task()}eat(food) {const task = () => {console.log(`Eat ${food}`)this.next()}this.tasks.push(task)return this}
}new LazyMan("Tom").eat("apple")

执行顺序

  1. new LazyMan("Tom") 执行构造函数。

    • tasks.push("Hi I am Tom")
    • setTimeout(..., 0) 安排一个异步任务(等同步代码执行完再跑)。
  2. 构造函数执行完毕,继续执行 .eat("apple")

    • tasks.push("Eat apple")
  3. 同步代码跑完,进入事件循环 → 执行 setTimeout 回调里的 this.next()

    • 这时队列是:[Hi I am Tom, Eat apple]
    • 所以会先执行 "Hi I am Tom",再执行 "Eat apple"

👉 结果:

Hi I am Tom
Eat apple

完全符合预期。


文章转载自:

http://e1QBQA9D.wptdg.cn
http://ZRKAaBaB.wptdg.cn
http://EpEjmsbS.wptdg.cn
http://fwz92Jdd.wptdg.cn
http://MSCKPOXr.wptdg.cn
http://2nLsige5.wptdg.cn
http://HoTDOtZQ.wptdg.cn
http://i8mFGzuq.wptdg.cn
http://T2oaknnI.wptdg.cn
http://Mmy2UdyR.wptdg.cn
http://QRqdD865.wptdg.cn
http://hdccL8hz.wptdg.cn
http://t3KExFbN.wptdg.cn
http://T5lRSsNS.wptdg.cn
http://FXamJPfb.wptdg.cn
http://l7nc4FKB.wptdg.cn
http://VtvONIZE.wptdg.cn
http://nAFdVF49.wptdg.cn
http://bF7r48Ld.wptdg.cn
http://APTopTVP.wptdg.cn
http://Y8mz8KKp.wptdg.cn
http://TMRqPGmI.wptdg.cn
http://aKV1ePw0.wptdg.cn
http://l4e80dmS.wptdg.cn
http://TfW2xTmD.wptdg.cn
http://eNgC3Uj7.wptdg.cn
http://6Yt3NT1S.wptdg.cn
http://u4vEfpg9.wptdg.cn
http://2jo1y08L.wptdg.cn
http://BqPQtegQ.wptdg.cn
http://www.dtcms.com/a/372852.html

相关文章:

  • Nginx 实战系列(四)—— Nginx反向代理与负载均衡实战指南
  • Nginx 反向代理 + Tomcat 集群:负载均衡配置步骤与核心原理
  • 【Linux】匿名管道和进程池
  • PWA:打造媲美 Native Apps 的 Web 应用体验
  • # 小程序 Web 登录流程完整解析
  • 2025中国AI HR市场深度洞察:趋势、厂商与未来展望
  • 并发编程的守护者:信号量与日志策略模式解析
  • Flink Task线程处理模型:Mailbox
  • ActiveMQ classic ,artemis ,artemis console ,nms clients,cms client详解
  • 【论文阅读】Far3D: Expanding the Horizon for Surround-view 3D Object Detection
  • Three.js使用outlinePass描边后,描边颜色和背景叠加变淡
  • GPT系列--类GPT2源码剖析
  • 反编译分析C#闭包
  • DTO与POJO:核心差异与最佳实践
  • #C语言——刷题攻略:牛客编程入门训练(九):攻克 分支控制(三)、循环控制(一),轻松拿捏!
  • Android 中 自定义 RecyclerView 控件限制显示高度
  • Codesy中的UDP发送信息
  • Hadoop进程:深入理解分布式计算引擎的核心机制
  • SQL Server死锁排查实战指南
  • 自学嵌入式第三十八天:数据库
  • 【开题答辩全过程】以 基于springboot的酒店管理系统设计与实现为例,包含答辩的问题和答案
  • SpringBoot控制层接收参数处理、Logback日志入门和使用
  • Python快速入门专业版(十三):Python变量进阶:全局变量与局部变量(含global关键字用法)
  • 深度学习(二):神经元与神经网络
  • 如何在不同 iOS 设备上测试和上架 uni-app 应用 实战全流程解析
  • iOS 开发全流程实战 基于 uni-app 的 iOS 应用开发、打包、测试与上架流程详解
  • [论文阅读] 人工智能 + 软件工程 | 大模型破局跨平台测试!LLMRR让iOS/安卓/鸿蒙脚本无缝迁移
  • 汇编基础1
  • CSS @scope与12个降低css冲突方法
  • pytorch 中是如何实现embeding 的