实现一个LazyMan, 可以按下列方式调用:
LazyMan("Hank")输出:
Hi! This is Hank!
LazyMan("Hank").sleep(10).eat("dinner") 输出:
Hi! This is Hank!
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") 输出:
Wake up after 5
Hi This is Hank!
Eat supper
方式一:
function _LazyMan(name) {
this.taskList = [];
this.introduce(name);
};
_LazyMan.prototype = {
_bind: function(method, fn) {
if(method === 'sleepFirst') {
this.taskList.unshift(fn);
}else {
this.taskList.push(fn);
}
},
next: function() {
if(this.taskList.length > 0) {
var fn = this.taskList.shift();
fn && fn();
}
},
introduce: function(name) {
var me = this;
// 在下一个事件循环启动任务
this._bind('introduce', function() {
me.log('Hi! This is '+ name +'!');
me.next();
});
setTimeout(function() {
me.next();
}, 0);
return this;
},
sleep: function(sec) {
var me = this;
this._bind('sleep', function() {
me.log('Wake up after ' + sec);
setTimeout(function() {
me.next();
}, sec * 1000);
});
return this;
},
eat: function(str) {
var me = this;
this._bind('eat', function() {
me.log('Eat '+ str +'~');
me.next();
});
return this;
},
sleepFirst: function (sec) {
var me = this;
this._bind('sleepFirst', function() {
me.log('Wake up after ' + sec);
setTimeout(function() {
me.next();
}, sec * 1000);
});
return this;
},
log: function(str) {
console.log(str);
}
};
var LazyMan = function(name) {
return new _LazyMan(name);
};
// LazyMan("Hank");
// LazyMan("Hank").sleep(10).eat("dinner");
// LazyMan("Hank").eat("dinner").eat("supper");
LazyMan("Hank").sleepFirst(5).eat("supper");
方式二:
class _LazyMan {
constructor(name) {
this.taskList = [];
this.introduce(name);
}
_bind(method, fn) {
if(method === 'sleepFirst') {
this.taskList.unshift(fn);
}else {
this.taskList.push(fn);
}
}
introduce(name) {
const me = this;
this._bind('introduce', function() {
return new Promise(function(resolve, reject) {
me.log('Hi! This is '+ name +'!');
resolve();
});
});
let sequence = Promise.resolve();
// 在下一个事件循环启动任务
setTimeout(function() {
for (let i = 0; i < me.taskList.length; i++) {
const func = (function (fn) {
return fn;
})(me.taskList[i]);
sequence = sequence.then(func);
};
}, 0);
return this;
}
sleep(sec) {
const me = this;
this._bind('sleep', function() {
return new Promise(function(resolve, reject) {
me.log('Wake up after ' + sec);
setTimeout(function() {
resolve();
}, sec * 1000);
});
});
return this;
}
eat(str) {
const me = this;
this._bind('eat', function() {
return new Promise(function(resolve, reject) {
me.log('Eat '+ str +'~');
resolve();
});
});
return this;
}
sleepFirst(sec) {
const me = this;
this._bind('sleepFirst', function() {
return new Promise(function(resolve, reject) {
me.log('Wake up after ' + sec);
setTimeout(function() {
resolve();
}, sec * 1000);
});
});
return this;
}
log(str) {
console.log(str);
}
};
var LazyMan = function(name) {
return new _LazyMan(name);
};
// LazyMan("Hank");
// LazyMan("Hank").sleep(10).eat("dinner");
// LazyMan("Hank").eat("dinner").eat("supper");
LazyMan("Hank").sleepFirst(5).eat("supper");