JavaScript 异步编程的优雅实现---手写 LazyMan

什么是 LazyMan?

LazyMan 是一个可以让你以链式调用的方式来定义并管理任务的工具。我们可以使用 LazyMan 来安排多个任务的顺序执行,并且每个任务可以有延迟时间。这样,我们可以避免深层嵌套的回调函数,使代码结构更加扁平。

需求分析

我们需要实现以下功能:

  1. 基本调用LazyMan('name'),打印 “Hi, I am name”。
  2. 延迟执行LazyMan.sleep(time),在指定时间后再执行下一个任务。
  3. 链式调用:支持多次调用,保持任务的顺序。

实现步骤

1. 创建基础 LazyMan 类

首先,我们创建一个 LazyMan 类,用于管理我们的任务队列。

class LazyMan {
    constructor(name) {
        this.tasks = [];
        console.log(`Hi, I am ${name}`);
        setTimeout(() => this.next(), 0); // 立即启动任务执行
    }

    next() {
        const task = this.tasks.shift(); // 获取下一个任务
        if (task) {
            task();
        }
    }

    sleep(time) {
        const fn = () => {
            setTimeout(() => {
                console.log(`Waited ${time} seconds`);
                this.next(); // 继续下一个任务
            }, time * 1000);
        };
        this.tasks.push(fn); // 将任务添加到队列
        return this; // 支持链式调用
    }

    eat(food) {
        const fn = () => {
            console.log(`I am eating ${food}`);
            this.next(); // 继续下一个任务
        };
        this.tasks.push(fn); // 将任务添加到队列
        return this; // 支持链式调用
    }
}

2. 添加链式调用功能

我们已经实现了 sleepeat 方法,并支持链式调用。接下来,让我们添加更多功能,比如 walk 方法。

walk(distance) {
    const fn = () => {
        console.log(`I walked ${distance} meters`);
        this.next(); // 继续下一个任务
    };
    this.tasks.push(fn);
    return this; // 支持链式调用
}

3. 完整代码示例

下面是完整的 LazyMan 实现:

class LazyMan {
    constructor(name) {
        this.tasks = [];
        console.log(`Hi, I am ${name}`);
        setTimeout(() => this.next(), 0); // 立即启动任务执行
    }

    next() {
        const task = this.tasks.shift(); // 获取下一个任务
        if (task) {
            task();
        }
    }

    sleep(time) {
        const fn = () => {
            setTimeout(() => {
                console.log(`Waited ${time} seconds`);
                this.next(); // 继续下一个任务
            }, time * 1000);
        };
        this.tasks.push(fn); // 将任务添加到队列
        return this; // 支持链式调用
    }

    eat(food) {
        const fn = () => {
            console.log(`I am eating ${food}`);
            this.next(); // 继续下一个任务
        };
        this.tasks.push(fn); // 将任务添加到队列
        return this; // 支持链式调用
    }

    walk(distance) {
        const fn = () => {
            console.log(`I walked ${distance} meters`);
            this.next(); // 继续下一个任务
        };
        this.tasks.push(fn);
        return this; // 支持链式调用
    }
}

// 使用示例
new LazyMan("Jack").sleep(2).eat("lunch").walk(5).sleep(3).eat("dinner");

4. 测试与输出结果

运行上述代码,我们可以看到以下输出:

Hi, I am Jack
Waited 2 seconds
I am eating lunch
I walked 5 meters
Waited 3 seconds
I am eating dinner

总结

通过手写 LazyMan,不仅体验到了 JavaScript 异步编程的魅力,也学习了任务管理的基本思路。LazyMan 的设计使得异步操作变得更加直观,链式调用的语法也让代码更具可读性。这种模式可以扩展到更复杂的异步操作中,帮助开发减少回调地狱的困扰,也是面试的高频考题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值