Open zeroone001 opened 5 years ago
function LazyMan(name) {
if (this instanceof LazyMan) {
this.name = name;
this.taskQueue = [];
this.firstTaskQueue = [];
console.log('Hi I am Tony');
return this;
} else {
return new LazyMan(name);
}
}
LazyMan.prototype.eat = function(food) {
var func = function() {
console.log('I am eating ' + food);
};
var _this = this;
this.isSleeping ?
this.taskQueue.push(func)
: setTimeout(function() {
if (_this.isSleepFirst) {
_this.firstTaskQueue.push(func)
} else {
console.log('I am eating ' + food)
}
});
return this;
}
LazyMan.prototype.sleep = function(time) {
var _this = this;
this.isSleeping = true;
setTimeout(function() {
_this.isSleeping = false;
console.log('等待了' + time + '秒...');
const func = _this.taskQueue.shift();
func.call(_this);
}, time * 1000)
return this;
}
LazyMan.prototype.sleepFirst = function(time) {
var _this = this;
this.isSleepFirst = true;
setTimeout(function() {
_this.isSleepFirst = false;
console.log('等待了' + time + '秒...');
_this.firstTaskQueue.forEach(func => {
func.call(_this);
});
}, time * 1000)
return this;
}
const LazyManClass2 = class {
constructor(name) {
console.log('Hi I am ' + name)
this.tasks = []
setTimeout(() => this.next())
}
sleepFirst(time) {
this.tasks.unshift(() => {
setTimeout(() => {
console.log(`等待了${time}秒...`)
this.next()
}, time * 1000)
})
return this
}
sleep(time) {
this.tasks.push(() => {
setTimeout(() => {
console.log(`等待了${time}秒...`)
this.next()
}, time * 1000)
})
return this
}
eat(food) {
this.tasks.push(() => {
console.log('Hi I eating ' + food)
this.next()
})
return this
}
next(...args) {
const task = this.tasks.shift()
task && task.call(this, ...args)
}
}
const LazyMan = name => new LazyManClass2(name)
来一个使用 async await 解题的方案
const LazyManClass2 = class {
constructor(name) {
console.log('Hi I am ' + name)
this.tasks = []
setTimeout(() => this.run())
}
sleepFirst(time) {
this.tasks.unshift(async() => {
return new Promise(resolve => {
setTimeout(() => {
console.log(`等待了${time}秒...`)
resolve()
}, time * 1000)
})
})
return this
}
sleep(time) {
this.tasks.push(async() => {
return new Promise(resolve => {
setTimeout(() => {
console.log(`等待了${time}秒...`)
resolve()
}, time * 1000)
})
})
return this
}
eat(food) {
this.tasks.push(async() => {
console.log('Hi I eating ' + food)
})
return this
}
run() {
this.tasks.reduce(async(prev, curr) => {
await prev
return curr()
}, Promise.resolve())
}
}
const LazyMan = name => new LazyManClass2(name)
class LazyManClass {
constructor(name) {
this.queues = [];
console.log(`Hi I am ${name}!`);
setTimeout(() => {
this.next();
}, 0);
}
eat(food) {
this.queues.push(() => {
console.log(`I am eating ${food}`)
this.next();
});
return this;
}
sleep(seconds) {
this.queues.push(() => {
setTimeout(() => {
console.log(`等待了${seconds}秒`);
this.next();
}, seconds * 1000)
});
return this;
}
sleepFirst(seconds) {
this.queues.unshift(() => {
setTimeout(() => {
console.log(`等待了${seconds}秒`);
this.next();
}, seconds * 1000)
});
return this;
}
next() {
if (this.queues.length){
const fn = this.queues.shift();
fn && fn();
}
}
}
function LazyMan(name) {
return new LazyManClass(name);
}
LazyMan('Tony').eat('lunch').eat('dinner').sleepFirst(5).sleep(4).eat('junk food');
感觉立即执行函数有点多余,没必要加上
class LazyMats {
constructor(name){
this.name=name;
this.arr=[];
console.log(`Hi I am ${this.name}`)
setTimeout(() => this.next(), 0);
}
eat(lunch){
let fast=()=>{
console.log(lunch)
this.next()
}
this.arr.push(fast)
return this;
}
sleep(time){
let fast=()=>{
setTimeout(()=>{
console.log(`等待了${time}秒`)
this.next()
}, time*1000);
}
this.arr.push(fast)
return this;
}
sleepFirst(time){
let fast=()=>{
setTimeout(()=>{
console.log(`首先等待了${time}秒`)
this.next()
}, time*1000);
}
this.arr.unshift(fast);
return this;
}
next(){
let fn=this.arr.shift()
fn&&fn()
}
}
function LazyMan(name){
return new LazyMats(name)
}
LazyMan('Tony').eat('lunch').sleep(1).eat('dinner').sleepFirst(2).eat('junk food')
interface ILazyMan {
name: string
stack: Array
eat(food: string): any
sleep(wait: number): any
sleepFirst(wait: number): any
next()
}
// 这里面需要注意的是, 等待是异步操作, 我们先用同步将所有的事件都放到栈里面, 然后, 在通过next进行顺序执行,
// 类似于 koa 里面的 next机制
class LazyMan implements ILazyMan {
name: string;
stack: Array
constructor(name: string) {
this.name = name;
this.stack = [];
console.log(`我是${this.name}`);
// 这个 setTimeout 用来先让他们将同步完成, 完成之后, 在进行异步执行
setTimeout(() => {
this.next();
});
}
sleep(wait: number) {
this.stack.push(() => {
setTimeout(() => {
console.log(`我休息了${wait}s`);
this.next();
}, wait * 1000);
});
return this;
}
eat(food: string): any {
this.stack.push(() => {
console.log(`我正在吃${food}`);
this.next();
});
return this;
}
sleepFirst(wait: number): object {
this.stack.unshift(() => {
setTimeout(() => {
console.log(`我先休息了${wait}s`);
this.next();
}, wait * 1000);
});
return this;
}
next() {
const fn = this.stack.shift();
fn && fn();
}
}
let lazyNan = (name: string): ILazyMan => new LazyMan(name);
lazyNan('小芳').eat('firstFood').eat('lunch').sleepFirst(5).sleep(5).eat('dinner');
function LazyMan (name){
class Man{
constructor(name){
this.name = name
this.say()
this.eventList = [] //事件队列
this.dispatchEvent = false //事件调度,开启事件队列执行
}
say(){
console.log(`hi i am ${this.name}`)
return this
}
eat(name){
this.dispatchEvent = true
this.eventList.push((fn)=>{
console.log(`i am eating ${name}`)
fn.call(this,true)
})
Promise.resolve().then(()=>{ this.pollEvent() })
return this
}
sleep(time){
this.dispatchEvent = true
this.eventList.push((fn)=>{
const now = new Date() //sleep settimeout 来实现
setTimeout(()=>{
fn.call(this,true)
},time*1000)
})
Promise.resolve().then(()=>{ this.pollEvent() })
return this
}
sleepFirst(time){
this.dispatchEvent = true
this.eventList.unshift((fn)=>{
const now = new Date() // sleep 用超时来实现(个人推荐这里用settime来实现)
while( Date.parse( new Date() ) - Date.parse(now) < 1000 * time ){
continue
}
fn.call(this,true)
})
Promise.resolve().then(()=>{ this.pollEvent() })
return this
}
pollEvent(hasPoll){
//事件循环执行器
if(!this.dispatchEvent && !hasPoll ) return
this.dispatchEvent = false
let current = this.eventList.shift()
current && current.call(this,this.pollEvent)
}
}
return new Man(name)
}
function LazyMan (name) {
console.log(`Hi I am ${name}`);
let a = {
sleeping: false,
firstSleep: false,
init: true,
sleepArr: new Set([]),
firstSleepTime: 0,
sleep (time) {
if (!checkSleep(this.sleep.bind(this, time))) {
return this;
}
this.sleeping = true;
setTimeout(() => {
this.sleeping = false;
handleSleep();
}, time * 1000);
return this;
},
eat (val) {
if (!checkSleep(this.eat.bind(this, val))) {
return this;
}
console.log(`I am eating ${val}`);
return this;
},
sleepFirst (time) {
this.firstSleepTime += time * 1000;
return this;
}
}
function checkSleep(fn) {
if (a.sleeping || a.init) {
a.sleepArr.add(fn);
return false;
} else {
return true;
}
}
setTimeout(() => {
setTimeout(() => {
a.init = false;
handleSleep();
}, a.firstSleepTime);
}, 0);
function handleSleep () {
const sleepArr = a.sleepArr;
for (let item of sleepArr) {
item();
sleepArr.delete(item);
if (a.sleeping) {
break;
}
}
}
return a;
}
用promise实现了一下,只写了sleep、eat 方法,sleepFirst 类似sleep
function LazyMan(name) {
let progress = new Promise((resolve, reject) => {
console.log(`Hi I am ${name}`);
resolve();
})
return {
sleep: function (time) {
progress = progress.then(() => {
console.log(`等待了${time}毫秒`);
return new Promise((resolve, reject) => {
setTimeout(() => resolve(), time)
})
})
return this
},
eat: function(text) {
progress = progress.then(() => {
return new Promise((resolve, reject) => {
console.log(`I am eating ${text}`);
resolve();
})
})
return this
}
}
}
class LazyManClass {
tasklist = []
constructor (name) {
console.log(`Hi I am ${name}`)
setTimeout(() => {
this.tasklist.reduce((preState, item) => {
return preState.then(item)
}, Promise.resolve())
}, 0)
}
eat (foods) {
this.tasklist.push(() => console.log(`I am eating ${foods}`))
return this
}
sleep (time) {
this.tasklist.push(() => {
return new Promise((res, rej) => {
setTimeout(() => {
res(console.log(`等待了${time}秒...`))
}, time * 1000)
})
})
return this
}
sleepFirst (time) {
this.tasklist.unshift(() => new Promise((res, rej) => {
setTimeout(() => {
res(console.log(`等待了${time}秒...`))
}, time * 1000)
}))
return this
}
}
const LazyMan = function (name) {
return new LazyManClass(name)
}
我用了很非常简单的方法实现的,不知道是否正确,请各位朋友指正。 思路如下: 1.给LazyMan设置是否休息的标志isSleep,sleep和sleepFirst方法都能将isSleep设置为真,并设置休息的时间sleepTime, eat方法根据isSleep决定是否延时执行 2.sleepFirst有优先执行权,sleepFirst中不设置setTimeout 3.要实现链式调用,所以每个方法都要返回this
class LazyManObject{
constructor(str) {
console.log('I am ' + str);
this.isSleep = false;
this.sleepTime = 0;
}
eat(str) {
setTimeout(() => {
if (!this.isSleep) {
console.log('I am eating ' + str);
} else {
setTimeout(() => {
console.log('I am eating ' + str);
this.sleepTime = 0;
this.isSleep = false;
return this;
}, this.sleepTime);
}
})
return this;
}
sleepFirst(num) {
this.sleepTime = num * 1000;
this.isSleep = true;
return this;
}
sleep(num) {
setTimeout(() => {
this.sleepTime = num * 1000;
this.isSleep = true;
})
return this;
}
}
function LazyMan(str) {
return new LazyManObject(str);
}
LazyMan('Jack').eat('breakfast').sleep(10).eat('lunch').sleepFirst(5);
class LazyManClass {
constructor(name) {
this._taskList = [];
console.info(`Hi I am ${name}`);
}
eat(foodName) {
this._addTask(() => {
console.info(`I am eat ${foodName}`);
return Promise.resolve();
});
return this;
}
sleep(seconds, first = false) {
let callback = () => new Promise((resolve) => {
setTimeout(() => {
resolve();
console.info(`等待了${seconds}秒钟...`);
}, seconds * 1000)
});
this._addTask(callback, first);
return this;
}
sleepFirst(seconds) {
return this.sleep(seconds, true);
}
_addTask(callback, first = false) {
let task = () => callback.call(this).finally(this._execute.bind(this));
if (first) {
this._taskList.unshift(task);
} else {
this._taskList.push(task);
}
this._execute();
}
_execute() {
if (this._taskList.length) {
clearTimeout(this._timeout);
this._timeout = setTimeout(() => {
if (this._taskList.length) {
let task = this._taskList.shift();
task();
}
}, 0);
}
}
}
function LazyMan(name) {
return new LazyManClass(name);
}
LazyMan('Tony').eat('lunch').eat('dinner').sleepFirst(5).sleep(10).eat('junk food');
感觉那些 next 的都是正统猿啊,学习了😂
function outSleep(t) {
return new Promise(r => {
setTimeout(() => {
console.log("");
console.log(`...outSleep ${t}`);
r();
}, 1000 * t);
});
}
function LazyMan(name) {
const lazy = {
_cbs: [],
_timer: null,
_init() {
if (name) console.log(`Hi I am ${name}`);
return this;
},
async _run() {
console.log("");
console.log(`===start`);
console.log(this._cbs);
console.log("");
for (let i = 0; i < this._cbs.length; i++) {
const fn = this._cbs[i];
await fn();
}
return this;
},
eat(food) {
this._cbs.push(function eat() {
console.log(`I am eating ${food}`);
});
clearTimeout(this._timer);
this._timer = setTimeout(() => {
this._run();
}, 0);
return this;
},
sleep(t) {
this._cbs.push(async function sleep() {
await outSleep(t);
});
return this;
},
sleepFirst(t) {
this._cbs.unshift(async function sleepFirst() {
await outSleep(t);
});
return this;
}
};
return lazy._init();
}
Hi I am Tony
===start
[ [AsyncFunction: sleepFirst],
[Function: eat],
[Function: eat],
[AsyncFunction: sleep],
[Function: eat] ]
...outSleep 5
I am eating lunch
I am eating dinner
...outSleep 1
I am eating junk food
简单点
function LazyMan(name) {
console.log('Hi I am ' + name)
const addTask = function (task, pos = 'last') {
if (!this.start) {
this.start = true
this.startTask()
}
if (pos === 'last') {
this.task.push(task)
} else {
this.task.unshift(task)
}
}
const startTask = function () {
setTimeout(async () => {
const task = [...this.task]
this.task = []
for (let i = 0; i < task.length; i++) {
let res = await task[i]()
}
this.start = false
})
}
const task = []
const sleep = function (time, pos = 'last') {
const taskFuc = () => {
return new Promise((resolve) => {
setTimeout(() => {
console.log('等待了', time)
resolve('sad')
}, time * 1000)
})
}
this.addTask(taskFuc, pos)
return this
}
const eat = function (food) {
this.addTask(() => console.log('i am eat', food))
return this
}
const sleepFirst = function (time) {
this.sleep(time, 'first')
return this
}
return {
task,
sleep,
eat,
startTask,
start: false,
addTask,
sleepFirst,
}
}
为什么需要立即执行函数?
var fn = (function (t) {
return function () {
setTimeout(() => {
console.log(`等待了${t}秒...`)
that.next();
}, t * 1000);
}
})(time);
直接如下不行吗?
var fn = function () {
setTimeout(() => {
console.log(`等待了${t}秒...`)
that.next();
}, t * 1000);
};
class LazyManClass {
constructor(name) {
this.name = name;
this.callback = [];
this.firstStack = [];
this.stack = [];
console.log(`Hi I am ${this.name}`);
setTimeout(this.next.bind(this), 0);
}
eat(food) {
this.stack.push(() => {
return new Promise((resolve, reject) => {
console.log(`I am eating ${food}`);
resolve();
});
});
return this;
}
sleep(seconds) {
this.stack.push(() => {
return new Promise((resolve, reject) => {
console.log(`等待了${seconds}秒`);
setTimeout(resolve, seconds * 1000);
});
});
return this;
}
sleepFirst(seconds) {
this.firstStack.push(() => {
return new Promise((resolve, reject) => {
console.log(`等待了${seconds}秒`);
setTimeout(resolve, seconds * 1000);
});
});
return this;
}
next() {
if (this.firstStack.length > 0) {
this.firstStack.shift()().then(this.next.bind(this));
} else if (this.stack.length > 0) {
this.stack.shift()().then(this.next.bind(this));
}
}
}
function LazyMan(name) {
return new LazyManClass(name);
}
以上大部分是以事件队列的算法实现,我这里提供发布订阅的一种算法,供大家参考:
class Event {
maps = {};
fire(type) {
const stack = this.maps[type] || [];
stack.every(listener => listener());
}
listen(type, listener) {
if (!this.maps.hasOwnProperty(type)) {
this.maps[type] = [];
}
this.maps[type].push(listener);
}
remove(type, listener) {
const index = this.maps.indexOf(listener);
this.maps.splice(index, 1);
}
}
let EventItem = new Event();
let init = false;
function LazyMan(name){
this.sleepState = false;
if(!init){
console.log('Hi I am ' + name);
init = true;
return new LazyMan(name);
}
}
LazyMan.prototype.sleep = function(time){
function s(){
this.sleepState = true;
setTimeout(() => {
console.log('等待了' + time + '秒...');
this.sleepState = false;
EventItem.fire('sleepOver')
}, time * 1000);
}
if(!this.sleepState){
s()
}else{
EventItem.listen('sleepFirstOver', () => {
s()
});
}
return this;
}
LazyMan.prototype.sleepFirst = function(time){
this.sleepState = true;
setTimeout(() => {
console.log('等待了' + time + '秒...');
this.sleepState = false;
EventItem.fire('sleepFirstOver')
}, time * 1000);
return this;
}
LazyMan.prototype.eat = function(type){
if(!this.sleepState){
console.log('I am eating ' + type)
}else{
EventItem.listen('sleepOver', () => {
console.log('I am eating ' + type)
});
}
return this;
}
LazyMan('Tony').eat('lunch').eat('dinner').sleepFirst(5).sleep(10).eat('junk food');
或许 next 的逻辑不应该放在队列里,队列应该做的只是保证根据优先级和先入先出来决定谁先出
class LazyMan {
constructor(name) {
this.name = name;
this.queue = [];
console.log(`Hi I am ${name}`);
setTimeout(this.apply.bind(this));
}
eat(something) {
this.queue.push(() => console.log(`I am eating ${something}`));
return this;
}
sleep(time) {
this.queue.push(async () => {
console.log(`等待了${time}秒...`);
return new Promise(res => setTimeout(res, time * 1000))
})
return this;
}
sleepFirst(time) {
this.queue.unshift(async () => {
console.log(`等待了${time}秒...`);
return new Promise(res => setTimeout(res, time * 1000))
})
return this;
}
async apply() {
const queue = this.queue;
while (queue.length) {
const todo = queue.shift();
await todo();
}
}
}
class LazyMan{
constructor (name) {
this.name = name
this.sleep = 0
this.sleepFirst = 0
console.log(`Hi I am ${this.name}`)
}
eat (what) {
setTimeout(()=>{setTimeout(()=>{console.log(`I am eating ${what}`)}, this.sleepFirst)}, this.sleep)
return this
}
Sleep (time) {
this.sleep = time
return this
}
SleepFirst (time) {
this.sleepFirst = time
return this
}
}
new LazyMan('Tony').eat('lunch').eat('dinner').Sleep(1000).eat('dinnerend').SleepFirst(2000)
有没有大佬解答一下,这里传立即执行函数的返回值(函数)和直接传红字部分的函数,有什么区别吗
立即执行函数的作用是在内部函数还没有执行的时候就已经为内部函数绑定好了对应参数的值,如果不用立即函数的话也可以用bind方法
var name = '小明' var fn = function (n){ console.log(`I am eating ${n}`) this.next() }.bind(null, name) 上面的代码实际上是让fn等于下面这个函数: function (){ console.log(`I am eating 小明`) this.next() }
这样一来无论你在什么地方执行fn都不需要传参数了,直接
fn()
不用参数也能达到和普通fn的fn(name )
效果一样了
为什么不直接
var fn = function () {
console.log(`I am eating ${name}`)
that.next();
}
// Lazyman
// 关键在于队列,taskQueue ,其实不是异步
function _Lazyman(name) {
return new Lazyman(name)
}
function Lazyman(name) {
this.name = name
this.taskQueue = []
// 但是启动的必须是异步,先都加入到队列,然后异步按照顺序执行
const asyncFunc = ()=>{
setTimeout(()=>{
console.log('I m '+ name)
this.runNext()
}, 0)
}
this.taskQueue.push(asyncFunc)
this.runNext() // 启动整个流程
}
Lazyman.prototype.eat = function(food) {
this.taskQueue.push(
// ()=>{
// setTimeout(()=>{
// console.log('eating ' + food)
// this.runNext()
// }, 0)
// }
()=>{
console.log('eating ' + food)
this.runNext()
}
)
return this
}
Lazyman.prototype.sleep = function(time) {
this.taskQueue.push( ()=> {
setTimeout(()=> {
this.runNext()
}, time)
} )
return this
}
Lazyman.prototype.runNext = function() {
let fn = this.taskQueue.shift() // 取第一个
fn && fn()
}
_Lazyman('kevin').eat('a').eat('b').sleep(3000).eat('c')
上面有的同学的思路很棒,就是不在队列的函数里面执行runNext,单独维护一个函数run整个queue里面的函数。
function LazyMan(name) {
console.log(`Hi I am ${name}`);
let tasks = [];
let run = () => {
if (tasks.length) {
let task = tasks.shift();
task && task();
}
};
setTimeout(() => {
run();
}, 0);
return {
sleep(time) {
tasks.push(() => {
setTimeout(() => {
console.log(`等待了${time}秒...`)
run();
}, 1000 * time);
});
return this;
},
sleepFirst(time) {
tasks.unshift(() => {
setTimeout(() => {
console.log(`等待了${time}秒...`)
run();
}, 1000 * time);
});
return this;
},
eat(what) {
tasks.push(() => {
console.log(`I am eating ${what}`);
run();
});
return this;
}
}
}
// test
LazyMan('Tony').eat('lunch').eat('dinner').sleepFirst(5).sleep(10).eat('junk food');
网上看到一个比较好的思路 [(https://www.jianshu.com/p/f1b7cb456d37)] 分析了考察的要点 “ 1.方法链式调用 2.类的使用和面向对象编程的思路 3.设计模式的应用 4.代码的解耦 5.最少知识原则,也即 迪米特法则(Law of Demeter) 6.代码的书写结构和命名 ”
var _now = function() {return new Date()}
function LazyMan(name) {
console.log(`Hi I am ${name}`)
setTimeout(() => {}, 0);
return this
}
LazyMan.prototype.eat = function (type) {
setTimeout(() => {
console.log(`I am eating ${type}`)
}, 0);
return this
};
LazyMan.prototype.sleep = function (sec) {
var now = new Date();
setTimeout(() => {
while (_now() - now < sec * 1000) {}
console.log(`等待了${sec}秒`);
}, 0);
return this
};
LazyMan.prototype.sleepFirst = function (sec) {
var now = new Date();
while (_now() - now < sec * 1000) {}
console.log(`等待了${sec}秒`);
return this
};
class LazyManClass {
constructor(name) {
this.timeoutNum = 0
this.timeoutArr = []
this.index = 0
console.log(`Hi I am ${name}`)
setTimeout(() => {
this.go()
}, 0);
}
eat(type) {
this.timeoutArr.push({
timeout: this.timeoutNum,
type
})
this.timeoutNum = 0
return this
}
sleep(timeout) {
this.timeoutNum += (timeout *= 1000)
return this
}
sleepFirst(timeout) {
this.timeoutArr = this.timeoutArr.map(item => {
item.delay = true
item.timeout = timeout * 1000
return item
})
return this
}
go() {
let curTimeoutItem = this.timeoutArr[this.index++]
if (!curTimeoutItem) return false
setTimeout(() => {
do
console.log(`I am eating ${curTimeoutItem.type}`)
while ((curTimeoutItem = this.timeoutArr[this.index++]) && curTimeoutItem.delay);
if (this.timeoutArr[--this.index]) this.go()
}, curTimeoutItem.timeout);
}
}
const LazyMan = name => {
return new LazyManClass(name)
}
LazyMan('Tony').eat('lunch').eat('dinner').sleepFirst(5).sleep(10).eat('junk food')
有大佬能解答下next()调用的时机吗,这个运行流程我有点看不懂=。=
这个跟event-loop(事件循环)有关,感兴趣的可以来了解一下我这篇文章:https://chen-cong.blog.csdn.net/article/details/97107219
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.name = name
this.queue = []
console.log(Hi I am ${name}
)
setTimeout(() => {
this.next()
},0)
}
sleepFirst(time) {
const fn = () => {
setTimeout(() => {
console.log(等待了${time}秒...
)
this.next()
}, time * 1000)
}
this.queue.unshift(fn)
return this
}
sleep(time) {
const fn = () => {
setTimeout(() => {
console.log(等待了${time}秒...
)
this.next()
},time * 1000)
}
this.queue.push(fn)
return this
}
eat(food) {
const fn = () => {
console.log(I am eating ${food}
)
this.next()
}
this.queue.push(fn)
return this
}
next() { const fn = this.queue.shift() fn && fn() } }
function LazyMan(name) { return new LazyManClass(name) } LazyMan('Tony').eat('lunch').eat('dinner').sleepFirst(5).sleep(4).eat('junk food');
你好,你的setTimeout里面没有乘1000,是毫秒,所以很快就输出了结果
在 2020年1月3日,下午2:42,GelaKola notifications@github.com 写道:
class LazyManClass { constructor(name) { this.name = name this.queue = [] console.log(
Hi I am ${name}
) setTimeout(() => { this.next() },0) }sleepFirst(time) { const fn = () => { setTimeout(() => { console.log(
等待了${time}秒...
) this.next() }, time) } this.queue.unshift(fn) return this }sleep(time) { const fn = () => { setTimeout(() => { console.log(
等待了${time}秒...
) this.next() },time) } this.queue.push(fn) return this }eat(food) { const fn = () => { console.log(
I am eating ${food}
) this.next() } this.queue.push(fn) return this }next() { const fn = this.queue.shift() fn && fn() } }
function LazyMan(name) { return new LazyManClass(name) } 你好你的这种写法如下调用,成功的输出了如下的输出,但是确没有真正等待5秒,4秒,而是一下子全部输出来的。
LazyMan('Tony').eat('lunch').eat('dinner').sleepFirst(5).sleep(4).eat('junk food'); // Hi I am Tony // 等待了5秒... // I am eating lunch // I am eating dinner // 等待了4秒... // I am eating junk food — You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/98?email_source=notifications&email_token=AGIDOG2TGU5EMXIFR6COSLLQ33M3TA5CNFSM4HGPR7PKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEIANLZY#issuecomment-570480103, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGIDOG7NTMOVO2AA7X3VCNLQ33M3TANCNFSM4HGPR7PA.
function LazyMan(name) {
return new function () {
this.name = name
console.log(`Hi I am ${this.name}`)
this.events = []
this.firstEvents = []
this.eat = function (el) {
this.events.push(() => console.log(`I am eating ${el}`))
return this
}
this.sleepFirst = function(time){
this.firstEvents = this.events.map((event)=>event)
this.events = []
setTimeout(()=>{
time != 0 ? console.log(`等待了${time}秒...`) : null
this.firstEvents.forEach(event => event())
},time * 1000)
return this
}
this.sleep = function (time) {
if(this.firstEvents==0) this.events = this.events.filter(event => event())
setTimeout(()=>{
console.log(`等待了${time}秒...`)
this.events.forEach(event => event())
},time * 1000)
return this
}
}
}
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 dinner
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
function LazyManClass(name) {
this.name = name;
console.log(`Hi I am ${this.name}`);
this.msgList = [];
Promise.resolve().then(async () => {
for(let i = 0; i < this.msgList.length; i ++) {
if (this.msgList[i].time > 0) {
await _sleep(this.msgList[i].time);
}
console.log(this.msgList[i].msg);
}
})
async function _sleep(t) {
await new Promise(resolve => setTimeout(() => resolve(), t*1000));
}
return this;
}
LazyManClass.prototype.eat = function(v) {
this.msgList.push({
time: 0,
msg: `I am eating ${v}`,
});
return this;
};
LazyManClass.prototype.sleep = function(t) {
this.msgList.push({
time: t,
msg: `等待了 ${t}秒...`,
});
return this;
};
LazyManClass.prototype.sleepFirst = function(t) {
this.msgList.unshift({
time: t,
msg: `等待了 ${t}秒...`,
});
return this;
};
function LazyMan(name) {
return new LazyManClass(name);
}
LazyMan('Tony').eat('lunch').eat('dinner').sleepFirst(5).sleep(10).eat('junk food');
class LazyManClass {
constructor(name) {
this.taskQueue = []
console.log(Hi I am ${name}
)
setTimeout(() => {
this.next()
})
}
sleep(second) {
let task = () => {
setTimeout(() => {
console.log(等待了${second}秒...
)
this.next()
}, second 1000)
}
this.taskQueue.push(task)
return this
}
sleepFirst(second) {
let task = () => {
setTimeout(() => {
console.log(等待了${second}秒...
)
this.next()
}, second 1000)
}
this.taskQueue.unshift(task)
return this
}
eat(food) {
let task = () => {
console.log('I am eating', food)
this.next()
}
this.taskQueue.push(task)
return this
}
next() {
let fn = this.taskQueue.shift()
fn && fn()
}
}
function LazyMan(name) {
return new LazyManClass(name)
}
class LazyMan {
constructor(name){
this.normalQueue = [];
this.sleepFistQueue = [];
this.name = name;
this.start();
return this;
}
start(){
this.delay(0, async ()=>{
let normalQueue = this.normalQueue;
let sleepFistQueue = this.sleepFistQueue;
// say hi
console.log(`Hi I am ${this.name}`);
// sleepFirstQueue
while(sleepFistQueue.length){
await sleepFistQueue.shift()();
}
// normalQueue
while(normalQueue.length){
await normalQueue.shift()();
}
})
}
delay(time = 0, fn){
return new Promise((resolve, reject) => {
window.setTimeout(()=>{
fn && fn();
resolve();
}, time*1000);
})
}
eat(food){
this.normalQueue.push(() => {
return this.delay(0, () => { console.log(`I am eating ${food}`)});
});
return this;
}
sleep(time){
this.normalQueue.push(() =>{
return this.delay(time, () => { console.log(`Delay ${time}s`)});
});
return this;
}
sleepFirst(time){
this.sleepFistQueue.push(() =>{
return this.delay(time, () => { console.log(`First delay ${time}s`)});
});
return this;
}
}
// test case
new LazyMan('Tony').eat('lunch').eat('dinner').sleepFirst(5).sleep(10).eat('junk food');
妈蛋,看了一遍大家的回答,发现我的写法最老派,果然是岁月不饶人...
function LazyMan(name) {
// 防止不通过new来调用
if (!(this instanceof LazyMan)) {
return new LazyMan(name);
}
this.name = name;
this.queue = [];
console.log(`I'm ${this.name}`);
return this.process();
}
LazyMan.prototype = {
process() {
clearTimeout(this.timer);
this.timer = setTimeout(() => {
let p = Promise.resolve();
while (this.queue.length) {
p = p.then(this.queue.shift());
}
}, 0);
return this;
},
eat(name) {
this.queue.push(() => {
return new Promise(resolve => {
console.log(name);
resolve();
});
});
return this.process();
},
sleep(sec) {
this.queue.push(() => {
return new Promise(resolve => {
setTimeout(() => {
console.log(`等待了${sec}秒...`);
resolve();
}, sec * 10); // 方便测试 应该为1000
});
});
return this.process();
},
sleepFirst(sec) {
this.queue.unshift(() => {
return new Promise(resolve => {
setTimeout(() => {
console.log(`等待了${sec}秒...`);
resolve();
}, sec * 10); // 方便测试 应该为1000
});
});
return this.process();
}
};
// 测试
var instance = LazyMan("Tony")
.eat("lunch")
.eat("dinner")
.sleepFirst(5)
.sleep(10)
.eat("junk food");
setTimeout(() => {
console.log("----again----");
instance
.eat("lunch")
.eat("dinner")
.sleepFirst(5)
.sleep(10)
.eat("junk food");
}, 1000);
function LazyMan (name) {
return new LazyManReduxStyle(name);
}
class LazyManReduxStyle {
constructor(name) {
this.name = name;
this.middlewares = [this._say()];
this.sleepFirstMiddlewares = [];
setTimeout(() => {
this._run();
});
}
sleepFirst(time) {
time = time * 1000;
this.sleepFirstMiddlewares.push(next => () => {
setTimeout(() => {
console.log(`Wake up after ${time} ms`);
next && next();
}, time);
});
return this;
}
sleep(time) {
time = time * 1000;
this.middlewares.push(next => () => {
setTimeout(() => {
console.log(`Wake up after ${time} ms`);
next && next();
}, time);
});
return this;
}
eat(food) {
this.middlewares.push(next => () => {
console.log(`Eat ${food}~`);
next && next();
});
return this;
}
_say() {
return next => () => {
console.log(`Hi, this is ${this.name}`);
next && next();
};
}
_run() {
this._applyMiddlewares([...this.sleepFirstMiddlewares, ...this.middlewares])();
}
_applyMiddlewares(middlewares) {
const [lastActionGenerator, ...restActionGenerators] = middlewares.reverse();
return compose(restActionGenerators)(lastActionGenerator());
}
}
function compose(funcs) {
return arg => funcs.reduce((acc, curr) => curr(acc), arg);
}
LazyMan('Hank').sleepFirst(3).eat('lunch').sleep(3).eat('dinner').sleepFirst(2);
最近看了下 Redux 中间件的原理,借鉴下他的思想写个 Lazyman 通过将下一个动作包裹成 next 放在前一个动作里面然后在适当的时机去调用 next,来实现流程的运行.
PS:这里的 sleepFirstMiddlewares 数组可以去掉,但是以前看到这题的时候他的要求是 sleepFirst 最先执行,但执行顺序与调用顺序相同,如果用 unshift 的话,无法实现执行顺序与调用顺序相同,所以就加了个新的数组,否则只用一个数组就够了
提升个难度: LazyMan('Tony').sleepFirst(5) // 等待了5秒 // Hi i am Tony
function LazyMan(name) {
console.log(`Hi I am ${name}`)
let totalSleepFirst = 0
let callbacks = []
function fire() {
if (totalSleepFirst) return
if (callbacks.length === 0) return
function run(){
if(callbacks.length === 0) return
callbacks.shift()().then(run)
}
run()
}
function eat(food) {
new Promise(resolve => {
setTimeout(() => {
resolve()
callbacks.push(() => Promise.resolve(console.log(`I am eating ${food}`)))
fire()
}, 0)
})
return man
}
function sleepFirst(delay) {
setTimeout(() => {
console.log(`等待了${delay}秒`)
totalSleepFirst -= delay
fire()
}, (delay + totalSleepFirst) * 1000)
totalSleepFirst += delay
return man
}
function sleep(delay) {
new Promise(resolve => {
setTimeout(() => {
resolve()
callbacks.push(() => new Promise(resolve => {
setTimeout(() => {
console.log(`等待了${delay}秒`)
resolve()
}, delay * 1000)
}))
fire()
}, 0)
})
return man
}
const man = {
eat,
sleepFirst,
sleep
}
return man
}
LazyMan('Tony').eat('lunch').eat('dinner').sleepFirst(5).sleepFirst(3).sleep(10).eat('junk food');
class LazyMan {
task = []
timer = null
constructor() {
return this.sayHi
}
sayHi = (name) => {
console.log(`Hi I am ${name}`)
return this
}
eat(food) {
this.task.push({ type: 'eat', value: food })
this.doIt()
return this
}
sleep(time) {
this.task.push({ type: 'sleep', value: time })
this.doIt()
return this
}
sleepFirst(time) {
this.task.unshift({ type: 'sleep', value: time })
this.doIt()
return this
}
_sleep (time) {
return new Promise(r => { setTimeout(() => { r() }, time * 1000) })
}
doIt () {
if (this.timer) clearTimeout(this.timer)
this.timer = setTimeout(async () => {
for (let i = 0; i < this.task.length; i++) {
const item = this.task[i]
if (item.type === 'eat') {
console.log(`I am eating ${item.value}`)
} else {
await this._sleep(item.value)
}
}
}, 0)
}
}
const lazyMan = new LazyMan()
lazyMan('Tony').eat('lunch').eat('dinner').sleepFirst(5).sleep(10).eat('junk food')
function LazyMan(name) { console.log(`I am ${name}`); var task = []; function execute() { var fn = task.shift(); fn && fn(); } // delay execute setTimeout(function() { execute(); }, 0); function _sleep(n = 0) { console.log(`${name} is sleeping ${n}`); setTimeout(function() { execute(); }, n * 1000); } function _eat(food) { console.log(`${name} is eating ${food}`); execute(); } var obj = { sleep: function() { task.push(_sleep.bind(null, ...arguments)); return obj; }, eat: function() { task.push(_eat.bind(null, ...arguments)); return obj; }, sleepFirst: function() { task.unshift(_sleep.bind(null, ...arguments)); return obj; } }; return obj; } LazyMan('Tony').eat('lunch').eat('dinner').sleepFirst(5).sleep(10).eat('junk food');
大哥 人家说的是构建个类 不是 方法
全是大佬 看不懂
class LazyManClass {
constructor(name) {
this.name = name;
this.taskList = [];
this.init();
}
init() {
console.log(`Hi I am ${this.name}`);
setTimeout(() => {
this.next();
}, 0);
}
next() {
const task = this.taskList.shift();
task && task();
}
sleepFirst(interval) {
const task = () => {
setTimeout(() => {
console.log(`等待了${interval}秒...`);
this.next();
}, interval * 1000);
};
this.taskList.unshift(task);
return this;
}
sleep(interval) {
const task = () => {
setTimeout(() => {
console.log(`等待了${interval}秒...`);
this.next();
}, interval * 1000);
};
this.taskList.push(task);
return this;
}
eat(food) {
const task = () => {
console.log(`I am eating ${food}`);
this.next();
};
this.taskList.push(task);
return this;
}
}
const LazyMan = (name) => new LazyManClass(name);
LazyMan('Tony').eat('apple').sleepFirst(5).sleep(3).eat('mongo');
(1)实例化对象的时候,会向setTimeout宏任务队列添加一个任务,此时script宏任务还未执完,所以不会立即执行setTimeout中的this.next()。
(2)然后执行script宏任务中的eat(),它添加了eatAppleTask到taskList的最后。
taskList = [eatAppleTask]。
(3)执行script宏任务中的sleepFirst(), 它添加了sleepFirstTask到taskList的最前面。
taskList = [sleepFirstTask,eatAppleTask]。
(4)执行script宏任务中的sleep(), 它添加了sleepTask到taskList的最后。
taskList = [sleepFirstTask,eatAppleTask,sleepTask]。
(5)执行script宏任务中的eat(),它添加了eatMongoTask到taskList的最后。
taskList = [sleepFirstTask,eatAppleTask,sleepTask,eatMongoTask]。
(6)此时script宏任务执行完毕,执行栈被清空。于是读取下一个宏任务,也就是第一步中的setTimeout,发现这个任务是可执行的(计时时间为0,早就过了)。将其回调函数提取到执行栈中执行。
(7) 于是执行回调函数this.next()。taskList中的第一个task,也就是sleepFirstTask被执行。它向setTimeout宏任务队列添加一个任务。此时执行栈中没有程序要执行,于是读取setTimeout宏任务,但是异步处理还未完成(需要3s,),所以不会提取该任务的回调函数去执行。等到3s之后,异步处理有结果了,立即将其回调提取到执行栈中执行。
(8)在sleepFirstTask中执行了this.next(),taskList中的第一个task,也就是eatAppleTask被执行。……
function LazyMan(name) {
const task = [];
this.eat = (food) => {
const fn = () => {
console.log("I am eating", food);
this.run();
};
task.push(fn);
return this;
};
this.sleep = (t) => {
const fn = () => {
setTimeout(() => {
console.log(`等待了${t}秒...`);
this.run();
}, t * 1000);
};
task.push(fn);
return this;
};
this.sleepFirst = (t) => {
const fn = () => {
setTimeout(() => {
console.log(`等待了${t}秒...`);
this.run();
}, t * 1000);
};
task.unshift(fn);
return this;
};
this.run = () => {
const fn = task.shift();
fn && fn();
};
setTimeout(() => {
this.run();
}, 0);
console.log("Hi I am", name);
return this;
}
`class LazyManFactory {
constructor(name) {
this.name = name
this.sayHi()
this.sleepTime = 0
}
sayHi () {
console.log(`Hi I am ${this.name}`)
}
sleep (time) {
process.nextTick(() => {
this.sleepTime += time * 1000
setTimeout(() => console.log(`等待了${time}秒...`), this.sleepTime)
})
return this
}
eat (type) {
process.nextTick(() => {
setTimeout(() => {
this.saySomething('eating', type)
}, this.sleepTime)
})
return this
}
sleepFirst (time) {
this.sleepTime += time * 1000
setTimeout(() => console.log(`等待了${time}秒...`), this.sleepTime)
return this
}
saySomething (action, type) {
console.log(`I am ${action} ${type}`)
}
}
function LazyMan (name) {
return new LazyManFactory(name)
}
// 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.next = null
this.cb = () => {}
}
eat(name){
return this.delay(0, () => console.log(name))
}
sleep(during = 0){
return this.delay(during)
}
sleepFirst(during = 0){
return this.delay(during)
}
delay(during, callback){
this.next = new LazyManClass()
this.cb = () => setTimeout(() => {
callback && callback()
this.next && this.next.cb()
}, during * 1000);
return this.next
}
start(){
setTimeout(() => this.cb(), 0);
return this
}
}
function LazyMan(name){
console.log("Hi I am " + name)
return new LazyManClass().start()
}
class LazyManClass {
constructor(name) {
this.taskList = [];
this.sayName(name);
setTimeout(() => {
this.start();
}, 0)
}
eat(food) {
this.taskList.push(() => {
console.log(`Hi I eating ${food}`)
const fn = this.taskList.shift();
fn && fn();
})
return this;
}
sleep(time) {
this.taskList.push(((time) => {
return () => {
setTimeout(() => {
console.log(`等待了${time / 1000}秒`)
const fn = this.taskList.shift();
fn && fn();
}, time)
}
})(time * 1000))
return this;
}
sleepFirst(time) {
this.taskList.unshift(((time) => {
return () => {
setTimeout(() => {
console.log(`等待了${time / 1000}秒`)
const fn = this.taskList.shift();
fn && fn();
}, time)
}
})(time * 1000))
return this;
}
sayName(name) {
console.log(`Hi I am ${name}`)
}
start() {
const fn = this.taskList.shift();
fn && fn();
}
}
function LazyMan(name) {
return new LazyManClass(name);
}
//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 People { constructor(name) { this.name = name; this.fns = []; this.fns.push({ m: 0, fn: () => { this.print('i am ' + name); } }) setTimeout(()=>{ this.run(); }) } print(str) { console.log(str); } run(){ if(this.fns.length){ const item = this.fns.shift(); if(item.m){ item.fn(); item.fn = null; } setTimeout(()=>{ item.fn && item.fn(); this.run(); },item.m) } } eat(str){ this.fns.push({m:0,fn:()=>{ this.print(str); }}) return this; } sleep(num){ this.fns.push({ m:num, fn:()=>{ this.print('延迟了'+num+'秒。。。'); } }) return this; }
sleepFirst(num){ this.fns.splice(1,0,{ m:num, fn:()=>{ this.print('延迟了'+num+'秒。。。'); } }) return this; } } new People('phillip').eat('dinner').eat('hahaha').sleepFirst(1000).sleep(2000).eat('lunch');
class LazyManClass {
constructor(name) {
console.log(`Hi I am ${name}`);
this.fns = [];
setTimeout(() => {
this.next();
}, 0);
}
eat(food) {
this.fns.push(() => {
console.log(`I am eating ${food}`);
this.next();
});
return this;
}
delay(time) {
return () => {
setTimeout(() => {
console.log(`等待了${time}秒...`);
this.next();
}, 1000 * time);
}
}
sleep(time) {
this.fns.push(this.delay(time));
return this;
};
sleepFirst(time) {
this.fns.unshift(this.delay(time));
return this;
};
next() {
this.fns.length > 0 && this.fns.shift()();
};
}
function LazyMan(name) {
return new LazyManClass(name);
}
function LazyManImpl(name) {
console.log(`Hi I am ${name}`);
this.microQueue = [];
this.macroQueue = [];
this.executionContext = 'NoContext';
}
LazyManImpl.prototype.eat = function (str) {
this.macroQueue.push(() => {
console.log(`I am eating ${str}`);
this.next();
});
this.scheduling();
return this;
};
LazyManImpl.prototype.sleepFirst = function (number) {
this.microQueue.push(() => {
setTimeout(this.next.bind(this), number * 1000);
});
this.scheduling();
return this;
};
LazyManImpl.prototype.sleep = function (number) {
this.macroQueue.push(() => {
setTimeout(this.next.bind(this), number * 1000)
});
this.scheduling();
return this;
};
LazyManImpl.prototype.next = function () {
if (this.executionContext !== 'RunContext') return;
if (this.microQueue.length > 0) {
const fn = this.microQueue.shift();
fn();
} else if (this.macroQueue.length > 0) {
const fn = this.macroQueue.shift();
fn();
} else {
this.executionContext = 'NoContext';
}
};
LazyManImpl.prototype.scheduling = function () {
switch (this.executionContext) {
case 'RunContext':
this.next();
break;
case 'NoContext':
this.executionContext = 'RegisterContext';
setTimeout(function () {
this.executionContext = 'RunContext';
this.next();
}.bind(this), 0);
break;
case 'RegisterContext':
break;
default:
// TODO warning
break;
}
};
const LazyMan = name => new LazyManImpl(name);
// LazyMan('Tony');
// LazyMan('Tony').sleep(10).eat('lunch');
// LazyMan('Tony').eat('lunch').sleep(10).eat('dinner');
LazyMan('Tony').eat('lunch').eat('dinner').sleepFirst(5).sleep(10).eat('junk food');
class LazyManClass {
constructor(name) {
this.name = name
this.sleepFirstAmount = 0
this.queue = []
Promise.resolve().then(() => {
this.run()
})
}
async run() {
this.hello(this.name)
if(this.sleepFirstAmount > 0) {
await new Promise((resolve) => {
setTimeout(resolve, this.sleepFirstAmount * 1000)
})
}
while(this.queue.length) {
const task = this.queue.shift()
const type = task.type
const value = task.value
if(type === 'eat') {
console.log(value)
continue
}
if (type === 'sleep') {
await new Promise((resolve) => { setTimeout(resolve, value * 1000) })
}
}
}
hello(name) {
console.log(name)
}
sleep(second) {
this.queue.push({type: 'sleep', value: second})
return this
}
sleepFirst(second) {
this.sleepFirstAmount += second
return this
}
eat(food) {
this.queue.push({type: 'eat', value: food})
return this
}
}
function LazyMan(name) {
return new LazyManClass(name)
}
LazyMan('Nathan').eat('apple').sleep(5).sleepFirst(3).eat('water')
function Man(name){
this.name = `Hi I am ${name}`
this.str = []
this.time = setTimeout(()=>{
this.parse()
},0)
}
Man.prototype.sleep = function(minutes){
this.str.push(`等待了${minutes}秒`)
clearTimeout(this.time)
this.time = setTimeout(()=>{
this.parse()
},0)
return this
}
Man.prototype.eat = function(food){
this.str.push(`I am eating ${food}`)
clearTimeout(this.time)
this.time = setTimeout(()=>{
this.parse()
},0)
return this
}
Man.prototype.sleepFirst = function(minutes){
this.str.unshift(`等待了${minutes}秒`)
clearTimeout(this.time)
this.time = setTimeout(()=>{
this.parse()
},0)
return this
}
Man.prototype.parse = function(){
console.log(this.name+'\n'+this.str.join('\n'))
}
function LazyMan(name){
return new Man(name)
}
Answer