Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

实现一个 LazyMan 【字节前端面试真题】 #382

Open
ChelesteWang opened this issue Jan 12, 2023 · 6 comments
Open

实现一个 LazyMan 【字节前端面试真题】 #382

ChelesteWang opened this issue Jan 12, 2023 · 6 comments

Comments

@ChelesteWang
Copy link
Contributor

实现一个LazyMan,可以按照以下方式调用:
LazyMan(“Hank”)输出:
Hi! This is Hank!

LazyMan(“Hank”).sleep(10).eat(“dinner”)输出
Hi! This is Hank!
//等待10秒..
Wake up after 10
Eat dinner~

LazyMan(“Hank”).eat(“dinner”).eat(“supper”)输出
Hi This is Hank!
Eat dinner~
Eat supper~

LazyMan(“Hank”).sleepFirst(5).eat(“supper”)输出
//等待5秒
Wake up after 5
Hi This is Hank!
Eat supper
以此类推。

@ChelesteWang ChelesteWang changed the title 实现一个 LazyMan 【番茄小说前端面试真题】 实现一个 LazyMan 【字节前端面试真题】 Jan 12, 2023
@ox4f5da2
Copy link

class LazyMan {
  /**
   * 构造函数
   * @param { string } name 
   */
  constructor(name) {
    this.taskQueue = []; // 任务队列
    this.sayHi(name);
    setTimeout(this._run.bind(this), 0);
  }
  /**
   * 打招呼
   * @param { string } name 
   */
  sayHi(name) {
    this.taskQueue.push(() => console.log(`Hi! This is ${name}!`));
    return this;
  }
  /**
   * 吃饭
   * @param { string } something 
   */
  eat(something) {
    this.taskQueue.push(() => console.log(`Eat ${something}~`));
    return this;
  }
  /**
   * 睡觉
   * @param { number } time 
   */
  sleep(time) {
    this.taskQueue.push(this._sleep(time));
    return this;
  }
  /**
   * 首先睡觉
   * @param { number } time 
   */
  sleepFirst(time) {
    this.taskQueue.unshift(this._sleep(time));
    return this;
  }
  /**
   * 执行任务队列
   */
  _run() {
    this.taskQueue.forEach(task => task());
  }
  /**
   * 睡觉函数
   * @param { number } time 
   */
  _sleep(time) {
    return () => {
      const start = +new Date();
      while (start + time * 1000 > +new Date());
      console.log(`Wake up after ${time}s`);
    }
  }
}

// new LazyMan("Hank").sleep(10).eat("dinner");
// new LazyMan("Hank").eat("dinner").eat("supper");
// new LazyMan("Hank").sleepFirst(5).eat("supper");

@ZhangYedi-cmd
Copy link

let _LazyMan = function (name) {
    this.taskQueue = []
    let that = this
    // 全部push完成之后,开始执行微任务队列
    // Promise.resolve().then(() => {
    //     // 将要执行的任务,全部丢进微任务队列执行
    //     let p = Promise.resolve()
    //     that.taskQueue.map(t => {
    //         p = p.then(t)
    //     })
    // })
    setTimeout(() => {
        that.taskQueue.map(async t => {
            await t()
        })
    })
}

_LazyMan.prototype.hold = function (time) {
    this.taskQueue.push(() => {
        return new Promise((resolve, reject) => {
            console.log(`sleep start`)
            setTimeout(() => {
                console.log(`sleep end`)
                resolve()
            }, time * 1000)
        })
    })
}

_LazyMan.prototype.sleep = function (time) {
    this.hold(time)
    return this
}

_LazyMan.prototype.sayHello = function (name) {
    this.taskQueue.push(() => {
        console.log(`hello ${name}`)
    })
    return this
}

let LazyMan = (name) => new _LazyMan(name)

LazyMan('yedi')
    .sleep(1)
    .sayHello("yedi")
    .sleep(5)
    .sayHello("h")

@bearki99
Copy link

bearki99 commented Jun 5, 2023

class LazyMan {
  constructor(name) {
    this.name = name;
    this.queue = [];
    console.log(`Hi this is ${this.name}`);
    setTimeout(() => {
      this.next();
    });
  }
  eat(arg) {
    const task = () => {
      console.log(`eat ${arg}`);
      this.next();
    };
    this.queue.push(task);
    return this;
  }
  next() {
    const task = this.queue.shift();
    task && task();
  }
  _sleep(time, isFirst) {
    const task = () => {
      console.log("sleep start");
      setTimeout(() => {
        console.log("sleep end");
        this.next();
      }, time * 1000);
    };
    if (isFirst) {
      this.queue.unshift(task);
    } else {
      this.queue.push(task);
    }
    return this;
  }
  sleep(time) {
    this._sleep(time, false);
    return this;
  }
  sleepFirst(time) {
    this._sleep(time, true);
    return this;
  }
}
const lazyMan = new LazyMan("张三");
lazyMan.eat("dinner").sleep(10).eat("super").sleep(5);

@4noth1ng
Copy link

class LLazyMan {
  constructor(name) {
    this.name = name;
    this.queue = [];
    this.sayName();
    this.run();
  }
  sayName() {
    this.queue.push(() => {
      console.log(`Hi! This is ${this.name}`);
    });
    return this;
  }
  sleep(time) {
    this.queue.push(() => this.timeWait(time));
    return this;
  }
  sleepFirst(time) {
    this.queue.unshift(() => this.timeWait(time));
    return this;
  }
  timeWait(time) {
    return new Promise((resolve) =>
      setTimeout(() => {
        console.log(`Wake up after ${time}`);
        resolve();
      }, time * 1000)
    );
  }
  eat(param) {
    this.queue.push(() => {
      console.log(`Eat ${param}`);
    });
    return this;
  }
  run() {
    setTimeout(async () => {
      for (const task of this.queue) {
        await task();
      }
    }, 0);
  }
}
const LazyMan = (name) => new LLazyMan(name);
// LazyMan("Hank").sleepFirst(5).eat("supper");
// LazyMan("Hank").eat("dinner").eat("supper");
LazyMan("c2c").sleep(2).eat("s");

@Liu6625
Copy link

Liu6625 commented Oct 19, 2023

class LazyManClass {
  constructor(name) {
    this.tasks = [];
    this.name = name;
    this.sayHi();
    this._run();
  }

  sayHi(){
    this.tasks.push(()=>console.log(`Hi!this is ${this.name}`))
    return this
  }

  sleep(ms) {
    this.tasks.push(() => this.sleepFn(ms));
    return this;
  }

  eat(name) {
    this.tasks.push(() => console.log(`Eat ${name}`))
    return this;
  }

  sleepFirst(ms) {
    this.tasks.unshift(() => this.sleepFn(ms));
    return this;
  }

  sleepFn(time) {
    return new Promise((resolve) =>
      setTimeout(() => {
        console.log(`Wake up after ${time}`);
        resolve();
      }, time * 1000)
    );
  }

  _run(){
    // setTimeout(()=>{
    //   this.tasks.forEach(async task => await task())
    // },0)

    setTimeout(async ()=>{
      for (const task of this.tasks) {
        await task();
      }
    },0)
  }
}

const LazyMan = (name) => new LazyManClass(name);

LazyMan("Hank").sleep(10).eat("dinner");

为什么forEach中用async并不能阻塞后面任务执行,用for of遍历时是可以的啊

@gswysy
Copy link

gswysy commented Mar 10, 2024

class Lazy {
    constructor(str) {
        this.taskQueue = [{
            msg: `Hi This is ${str}`,
            sleep: 0
        }]
        this.sleepTime = 0
        Promise.resolve().then(() => {
            this._run()
        })
    }
    sleep(t) {
        this.sleepTime = t
        return this
    }
    eat(str) {
        const obj = {
            msg: `Eat ${str}`,
            sleep: this.sleepTime
        }
        this.sleepTime = 0
        this.taskQueue.push(obj)
        return this
    }
    sleepFirst(t) {
        this.taskQueue[0].sleep = t
        return this
    }
    _run() {
        const delay = (time) => {
            return new Promise(resovle => {
                setTimeout(() => {
                    resovle()
                }, time);
            })
        }
        const _call = async () => {
            for (const task of this.taskQueue) {
                if (task.sleep) {
                    console.log(`Wake up after ${task.sleep}`)
                    await delay(task.sleep * 1000)
                }
                console.log(task.msg)
            }
        }
        _call()
    }
}

function LazyMan(str) {
    return new Lazy(str)
}

LazyMan('gsw').sleepFirst(5).sleep(3).eat('dzq').sleep(4).eat('ysy').sleep(3).eat('zbc')

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants