任务队列实现函数链式调用

48 阅读1分钟

实现任意长度链式调用的关键在于每个函数加入队列以后返回对象本身,以便于进行下一次调用。

实现延时等待函数的关键在于相应函数调用结束以后再进行下一次对任务队列是否为空的检查。

class的写法
class Chains {
    constructor() {
        this.queue = []
        setTimeout(() => {
            this.next()
        }, 0)
    }

    next() {
        let fn = this.queue.shift()
        fn && fn()
    }

    eat() {
        let fn = () => {
            console.log("eat")
            this.next()
        }
        this.queue.push(fn)
        return this
    }

    sleep() {
        let fn = () => {
            console.log("sleep")
            this.next()
        }
        this.queue.push(fn)
        return this
    }

    wait(time) {
        let fn = () => {
            setTimeout(() => {
                console.log("wait " + time + " seconds")
                this.next()
            }, time * 1000);
        }
        this.queue.push(fn)
        return this
    }
}

let chain = new Chain()
chain.eat().wait(8).sleep()
function写法

在原型链上添加函数时需要使用function而不是箭头函数。

function Chain() {
    this.queue = []

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

    return this
}

Chain.prototype.next = function () {
    let fn = this.queue.shift()
    fn && fn()
}

Chain.prototype.eat = function () {
    let fn = () => {
        console.log("eat")
        this.next()
    }
    this.queue.push(fn)
    return this
}

Chain.prototype.sleep = function () {
    let fn = () => {
        console.log("sleep")
        this.next()
    }
    this.queue.push(fn)
    return this
}

Chain.prototype.wait = function (time) {
    let fn = () => {
        setTimeout(() => {
            console.log("wait " + time + " seconds")
            this.next()
        }, time * 1000)
    }
    this.queue.push(fn)
    return this
}

let chain = new Chain()
chain.eat().wait(8).sleep()