lazyman的两种实现方式

2017-02-12 Lim Geng 更多博文 » 博客 » GitHub »

前端 javascript lazyman promise

原文链接 http://gengliming.com/2017/02/12/some-implements-of-lazyman/
注:以下为加速网络访问所做的原文缓存,经过重新格式化,可能存在格式方面的问题,或偶有遗漏信息,请以原文为准。


最近在网上看到有部分人在面试(比如1月面试记)的时候被问到了LazyMan,而且网友也有不同的实现方式。这里我用两种方式实现了lazyman,以供参考,如有更好的方法,欢迎留言。

队列

这种方式,每次都是往queue里添加执行函数,next函数用来决定什么时候调用下一个函数。

var LazyMan = function LazyMan (name) {
    if (!(this instanceof LazyMan)) return new LazyMan(name);
    this.queue = [() => {
        console.log(`hello ${name}`);
        this.next();
    }];

    setTimeout(() => {
        this.next();
    });
};

LazyMan.prototype.next = function next() {
    if (this.queue.length) {
        this.queue.shift()();
    }
}

LazyMan.prototype.eat = function eat(food) {
    this.queue.push(() => {
        console.log(`eat ${food}`)
        this.next();
    });
    return this;
};

LazyMan.prototype.sleep = function sleep(sec) {
    this.queue.push(() => {
        setTimeout(() => {
            console.log(`wake up after  ${sec}s`);
            this.next();
        }, sec * 1000);
    });
    return this;
};

LazyMan.prototype.sleepFirst = function sleepFirst(sec) {
    this.queue.unshift(() => {
        setTimeout(() => {
            console.log(`wake up after ${sec}s`);
            this.next();
        }, sec * 1000);
    });
    return this;
};
LazyMan('glm').eat('apple').sleep(2).eat('banana').sleepFirst(3).eat('peach');

这里有一点需要点一下,就是我的queue已经就绪了,该怎么执行呢,这里用到了setTimeout(function () {}, 0);,在下一次事件循环就开始执行,因为所有向队列添加函数都是在同一次事件循环里。

Promise

var LazyMan = function LazyMan(name) {
    if (!(this instanceof LazyMan)) return new LazyMan(name);
    this.firstPromise = this.promise = new Promise((fullfill, reject) => {
        console.log(`hello ${name}`);
        fullfill();
    });
};

LazyMan.prototype.eat = function eat(food) {
    this.promise = this.promise.then(() => {
        console.log(`eat ${food}`);
    });
    return this;
};

LazyMan.prototype.sleep = function sleep(sec) {
    this.promise = this.promise.then(() => {
        return new Promise((fullfill, reject) => {
            setTimeout(() => {
                console.log(`wake up after ${sec}s`);
                fullfill();
            }, sec * 1000);
        });
    });
    return this;
};

LazyMan.prototype.sleepFirst = function sleepFirst(sec) {
    // NOTHING
}

LazyMan('glm').eat('apple').sleep(2).eat('banana').eat('peach');

这种方式我还没想好如何实现sleepFirst,如果有知道的朋友,欢迎留言。