一道有意思的JavaScript面试题

 

题目分析

1. 函数链调用,那么每个函数必然返回 this对象指向本身才能继续无限调用

2. 函数链调用上只要有sleepFirst函数 ,这个函数必须自动提前执行,就 可以否定 函数通过 直接执行 的方式实现,那么就只能想到 事件队列方式 实现

 

原型对象方式实现

function LazyMan(name){
    return new LazyManClass(name)
}

function  mySleep(ms){
    return new Promise((resolve,reject)=>{
        setTimeout(resolve,ms*1000)
    })
}
function LazyManClass(name){
    this.name = name;
    this.task = [];
    console.log(`Hi I am Tony`)
    return this
}
LazyManClass.prototype.mySleep =  function(ms){
    return new Promise((resolve,reject)=>{
        setTimeout(resolve,ms*1000)
    })
}

LazyManClass.prototype.nextTickTask =  function(){
    if(this.hasTask){
        return
    }
    this.hasTask = true
    new Promise(e=>{e()}).finally(async e=>{
        while(this.task.length>0){
            let { value, task } = this.task.shift();
            if(task === 'sleepFirst' || task === 'sleep'){
                await this.mySleep(value)
                console.log(`等待 ${value*1000}秒`)
            }else if(task === 'eat'){
                console.log(`I am eatting ${value}`)
            }
        }    
        this.hasTask = false
    })
    return this
}
LazyManClass.prototype.sleepFirst =  function(ms){
    this.task.unshift({task:'sleepFirst',value:ms})
    this.nextTickTask()
    return this
}
LazyManClass.prototype.sleep =  function(ms){
    this.task.push({task:'sleep',value:ms})
    this.nextTickTask()
    return this
}
LazyManClass.prototype.eat =  function(str){
    this.task.push({task:'eat',value:str})
    this.nextTickTask()
    return this
}

function LazyMan(name){
    return new LazyManClass(name)
}

LazyMan('Tony').eat('lunch').sleep(3).sleepFirst(5).eat('lunch1')

class类实现

class LazyManClass{
    constructor(name=''){
        this.name = name
        this.task = []
        console.log(`I am eating ${name}`)
    }
    nextTickTask(){
        if(this.hasTask){
            return
        }
        this.hasTask = true
        new Promise(e=>{e()}).finally(async e=>{

            while(this.task.length>0){
                let { value, task } = this.task.shift();
                if(task === 'sleepFirst' || task === 'sleep'){
                    await this.mySleep(value)
                    console.log(`等待 ${value*1000}秒`)
                }else if(task === 'eat'){
                    console.log(`I am eatting ${value}`)
                }
            }    
            this.hasTask = false
        })
        return this
    }
    mySleep(ms){
        return new Promise((resolve,reject)=>{
            setTimeout(resolve,ms*1000)
        })
    }
    sleepFirst(ms){
        this.task.unshift({task:'sleepFirst',value:ms})
        this.nextTickTask()
        return this
    }
    sleep(ms){
        this.task.push({task:'sleep',value:ms})
        this.nextTickTask()
        return this
    }
    eat(str){
        this.task.push({task:'eat',value:str})
        this.nextTickTask()
        return this
    }
}
function LazyMan(name){
    return new LazyManClass(name)
}
LazyMan('Tony').eat('lunch').sleep(3).sleepFirst(5).eat('lunch1')

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一杯码农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值