字节一面的一道好题:如何实现异步链式调用

字节一面出了一道好题:实现一个异步链式调用的效果:new CodeMan().eat("lunch").sleep(10).eat("dinner")sleep(10)表示要异步地等待10s以后执行后面的内容。

面试官只给了一个关键字的提示:队列。我是那个百思不得其解啊!

面试后,我想了想,调用阶段(是同步任务,会先执行)先用一个队列把任务收集起来(这里把eat和sleep统称为”任务“),然后用”宏任务在同步任务执行完以后才执行“这个特性,来搞一个”假递归“,即当前任务执行完后再把下一个任务扔进宏任务队列。

而第一个任务,用setTimeout(process,0)调用,因为以上特性,所以它会在收集完毕以后才执行。

于是我们抽象出一个process函数,它的工作是:执行当前的宏任务。

更新:发出文章后看到前人的实现,感觉比我这个做法复杂些……

代码
function CodeMan(){
    let EAT = Symbol(),SLEEP = Symbol()
    function Task(type,arg){
        this.type = type
        if(type === EAT) this.food = arg
        else this.time = arg
    }
    let q = []
    this.eat = (food) => {
        q.push(new Task(EAT,food))
        return this
    }
    this.sleep = (time) => {
        q.push(new Task(SLEEP,time*1000))
        return this
    }
    let process = () => {
        if(!q.length) return
        let u = q.shift()
        if(u.type === EAT){
            console.log(u.food)
            setTimeout(process,0)
        }
        else{
            setTimeout(process,u.time)
        }
    }
    setTimeout(process,0)
}
new CodeMan().eat("lunch").sleep(2).eat("dinner").sleep(2).eat('breakfast')
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值