8

a topic

See a very interesting topic: implement a method that supports chained calls.

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

solution

Not much to say, go directly to the code:

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');

problem analysis

For this topic, we must first know how to complete the chain call, which is to set up a class, and the end of the method declared in the class will return a reference to the instance of the class, so that the chain call can be made.

So we create a LazyMan class.

Next is how to ensure sequential execution, which is to use an array of callbacks. After each function call, it will check whether the callback is empty. If it is not empty, it will continue to execute.
At the same time, in order to ensure that before the first execution, all functions will be traversed and the priority will be confirmed. We use setTimeout in the constructor to create a micro task, which will wait for all the macro tasks in the main function to be executed before starting. real function execution.

So the key point of this topic:

  • callbacks: Stores a list of function executions to facilitate adjusting the execution order.
  • class: Create a class that provides a unified parent for each function, and guarantees chained calls by returning this.
  • next: execute the function step by step to ensure that all functions will be executed in sequence after the sequence is confirmed.
  • setTimeout:

    • timer.
    • Create a microtask that is guaranteed to start executing after the main function has been traversed.

赵帅强
3.3k 声望380 粉丝

前端打工人