【前端100問】Q56:要求設計 LazyMan 類,實現以下功能。

寫在前面

此係列來源於開源項目:前端 100 問:能搞懂 80%的請把簡歷給我
爲了備戰 2021 春招
每天一題,督促自己
從多方面多角度總結答案,豐富知識
要求設計 LazyMan 類,實現以下功能。
簡書整合地址:前端 100 問

正文回答

題目
LazyMan("Tony");
// Hi I am Tony

LazyMan("Tony").sleep(10).eat("lunch");
// Hi I am Tony
// 等待了10秒...
// I am eating lunch

LazyMan("Tony").eat("lunch").sleep(10).eat("dinner");
// Hi I am Tony
// I am eating lunch
// 等待了10秒...
// I am eating diner

LazyMan("Tony")
  .eat("lunch")
  .eat("dinner")
  .sleepFirst(5)
  .sleep(10)
  .eat("junk food");
// Hi I am Tony
// 等待了5秒...
// I am eating lunch
// I am eating dinner
// 等待了10秒...
// I am eating junk food
回答
class LazyManClass {
  constructor(name) {
    this.taskList = [];
    this.name = name;
    console.log(`Hi I am ${this.name}`);
    setTimeout(() => {
      this.next();
    }, 0);
  }
  eat(name) {
    var that = this;
    var fn = (function (n) {
      return function () {
        console.log(`I am eating ${n}`);
        that.next();
      };
    })(name);
    this.taskList.push(fn);
    return this;
  }
  sleepFirst(time) {
    var that = this;
    var fn = (function (t) {
      return function () {
        setTimeout(() => {
          console.log(`等待了${t}秒...`);
          that.next();
        }, t * 1000);
      };
    })(time);
    this.taskList.unshift(fn);
    return this;
  }
  sleep(time) {
    var that = this;
    var fn = (function (t) {
      return function () {
        setTimeout(() => {
          console.log(`等待了${t}秒...`);
          that.next();
        }, t * 1000);
      };
    })(time);
    this.taskList.push(fn);
    return this;
  }
  next() {
    var fn = this.taskList.shift();
    fn && fn();
  }
}
function LazyMan(name) {
  return new LazyManClass(name);
}
function LazyMan(name) {
  class Man {
    constructor(name) {
      this._queues = [];
      console.log(`Hi I am ${name}`);
      Promise.resolve().then(() => {
        this.next();
      });
      return this;
    }

    _sleep = (time) => {
      return new Promise((resolve) => setTimeout(resolve, time * 1000));
    };

    eat(type) {
      this._queues.push(() => {
        console.log(`I am eating ${type}`);
        this.next();
      });
      return this;
    }
    sleepFirst(time) {
      this._queues.unshift(() => {
        this._sleep(time).then(() => {
          console.log(`等待了${time}秒`);
          this.next();
        });
      });
      return this;
    }

    sleep(time) {
      this._queues.push(() => {
        this._sleep(time).then(() => {
          console.log(`等待了${time}秒`);
          this.next();
        });
      });
      return this;
    }

    next() {
      const fn = this._queues.shift();
      fn && fn();
    }
  }

  return new Man(name);
}
function LazyMan(username) {
  console.log(" Hi I am " + username);

  var temp = {
    taskList: [],
    sleepFirst(timeout) {
      return () => {
        setTimeout(() => {
          console.log(`等待了${timeout}秒...`);
          this.next();
        }, timeout * 1000);
      };
    },
    sleep(timeout) {
      return () => {
        setTimeout(() => {
          console.log(`等待了${timeout}秒...`);
          this.next();
        }, timeout * 1000);
      };
    },
    eat(type) {
      return () => {
        console.log(`I am eating ${type}`);
        this.next();
      };
    },
    next() {
      var fn = this.taskList.shift();
      fn && fn();
    },
  };

  var proxy = new Proxy(temp, {
    get(target, key, receiver) {
      return function (...rest) {
        if (key === "sleepFirst") {
          target.taskList.unshift(target[key](rest));
        } else {
          target.taskList.push(target[key](rest));
        }
        return receiver;
      };
    },
  });

  setTimeout(() => {
    temp.next();
  }, 0);
  return proxy;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章