前端链式调用和事件循环

我们通过一道题目来理解前端链式调用和事件循环。

实现一个方法,支持链式调用:

lazyman.lazy('Lisa').sleep(3).sleepFirst(4).eat('lunch');
// 4s后输出:Sleep Afater 4
// 输出:I'm Lisa
// 3s后输出:Sleep After 3
// 输出:I'm eat lunch

解法

class LazyMan {
    callbacks = [];

    constructor() {
        this.next();
    }

    next() {
        setTimeout(() => {
            const firstFn = this.callbacks.shift();
            firstFn && firstFn();
        }, 0);
    }

    lazy(name) {
        this.callbacks.push(() => {
            console.log(`Hi, I'm ${name}`);
            this.next();
        });
        return this;
    }

    sleep(time) {
        this.callbacks.push(() => {
            setTimeout(() => {
                console.log(`Sleep after ${time}`);
                this.next();
            }, time * 1000);
        });
        return this;
    }

    sleepFirst(time) {
        this.callbacks.unshift(() => {
            setTimeout(() => {
                console.log(`Sleep after ${time}`);
                this.next();
            }, time * 1000);
        });
        return this;
    }

    eat(item) {
        this.callbacks.push(() => {
            console.log(`I am eat ${item}`);
            this.next();
        });
        return this;
    }
}

const lazyman = new LazyMan();
lazyman.lazy('Lisa').sleep(3).sleepFirst(4).eat('lunch');

题解分析

这个题目,首先要知道如何完成链式调用,就是设置一个类,类中声明的方法的结尾最后都会重新返回该类实例的引用,这样就能够链式调用了。

所以我们创建一个LazyMan的类。

接下来是如何保证顺序执行,那就是使用一个回调数组,每个函数调用后会检查一次回调是否为空,如果不为空,则继续执行。
同时为了保证第一次执行前,会先进行一遍所有函数的遍历,确认优先级,我们在constructor里面使用setTimeout进行创建一个微任务,这样会等main函数里的宏任务全部执行完,才会开始真正的函数执行。

所以这个题目的关键点:

  • callbacks: 存储函数执行的列表,方便调整执行顺序。
  • class:创建一个类,为每个函数提供统一的父亲,通过return this保证链式调用。
  • next:分步执行函数,保证确认好顺序后,所有的函数都会被依次执行。
  • setTimeout:
    • 定时器。
    • 创建一个微任务,保证在main函数遍历后再开始执行。

「点点赞赏,手留余香」

1

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:
1. 本站所有文章教程及资源素材均来源于网络与用户分享或为本站原创,仅限用于学习和研究。
2. 如果内容损害你的权益请联系客服QQ:1642748312给予处理。
码云笔记 » 前端链式调用和事件循环

发表回复

IT互联网行业相关广告投放 更专业 更精准

立即查看 联系我们