手机发布,空格都是一个个敲出来的,请网友见谅,以后会改进
先看网上版本:
function _LazyMan(name) {
this.tasks = [];
var self = this;
var fn = (function(n) {
var name = n;
return function() {
console.log("Hi! This is " + name + "!");
self.next();
}
})(name);
this.tasks.push(fn);
setTimeout(function() {
self.next();
},
0); // 在下一个事件循环启动任务
}
/* 事件调度函数 */
_LazyMan.prototype.next = function() {
var fn = this.tasks.shift();
fn && fn();
}
_LazyMan.prototype.eat = function(name) {
var self = this;
var fn = (function(name) {
return function() {
console.log("Eat " + name + "~");
self.next()
}
})(name);
this.tasks.push(fn);
return this; // 实现链式调用
}
_LazyMan.prototype.sleep = function(time) {
var self = this;
var fn = (function(time) {
return function() {
setTimeout(function() {
console.log("Wake up after " + time + "s!");
self.next();
},time * 1000);
}
})(time);
this.tasks.push(fn);
return this;
}
_LazyMan.prototype.sleepFirst = function(time) {
var self = this;
var fn = (function(time) {
return function() {
setTimeout(function() {
console.log("Wake up after " + time + "s!");
self.next();
},time * 1000);
}
})(time);
this.tasks.unshift(fn);
return this;
}
/* 封装 */
function LazyMan(name) {
return new _LazyMan(name);
}
LazyMan('Hank').sleepFirst(5).sleep(10).eat('dinner')
以上原理:用setTimeout模拟线程,有一个事件处理队列,然后每一个事件内部会调用事件调度函数。
写的也是非常巧妙,想了一下,这种异步处理,promise是最擅长干这个的,于是自己用Promise试着实现了一个:
function _lazyman(name) {
this.orderPromise = this.newPromise(); //定义顺序promise对象
this.insertPromise = this.newPromise(); //定义插入promise对象
this.order(function(resolve) {
console.log(name);
resolve();
})
}
_lazyman.prototype = {
/*实例化promise对象工厂
*/
newPromise: function() {
return new Promise(function(resolve, reject) {
resolve();
})
},
order: function(fn) {
var self = this;
this.orderPromise = this.orderPromise.then(function() {
return new Promise(function(resolve, reject) {
//如果有insertPromise,阻塞orderPromise.
self.fir ? self.insertPromise.then(function() {
fn(resolve)
}) : fn(resolve);
})
})
},
insert: function(fn) {
var self = this;
this.fir = true;
this.insertPromise = this.insertPromise.then(function() {
return new Promise(function(resolve, reject) {
fn(resolve) self.fir = false;
})
})
},
firstTime: function(time) {
this.insert(function(resolve) {
setTimeout(function() {
console.log('wait ' + time + ' s, other logic');
resolve();
},time * 1000)
}) return this;
},
eat: function(fan) {
this.order(function(resolve) {
console.log(fan + '~~') resolve();
})
return this;
},
sleep: function(time) {
this.order(function(resolve) {
setTimeout(function() {
console.log('sleep ' + time + ' s');
resolve()
},time * 1000);
})
return this;
}
}
//接口封装。
function lazyman(name) {
return new _lazyman(name);
}
//调用测试
lazyman('RoryWu').firstTime(1).sleep(2).firstTime(3).eat('dinner').eat('breakfast');
// 弹出:
// wait 1 s, other logic
// wait 3 s, other logic
// RoryWu
// sleep 2 s
// dinner~~
// breakfast~~
浙公网安备 33010602011771号