关于前端:一道题解前端链式调用和事件循环

50次阅读

共计 1235 个字符,预计需要花费 4 分钟才能阅读完成。

一道题目

看到一个很乏味的题目:实现一个办法,反对链式调用。

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 函数遍历后再开始执行。

正文完
 0