我想用javascript实现一个构造函数,它的名称是Man()
,它有一个异步方法,它的名字是sleep(ms)
,它将休眠ms
秒。它也有一些同步方法,如eat()
。
我想实现这样的目标:
- 链调用
- async方法和sync调用的正确顺序
例如:
new Man('Tom').sleep(3).eat('dinner')
// output: 'Hello, I am Tom'
// After 3 seconds
// output: 'Eat Dinner'
我试过这个:
function Man(name) {
console.log(`Hello, I am ${name}`)
return this
}
Man.prototype.sleep = function(ms) {
setTimeout(() => {
return this
}, ms)
}
Man.prototype.eat = function() {
console.log('Eat Dinner')
return this
}
但它并没有像预期的那样工作,它发现了一个错误:Uncaught TypeError: Cannot read property 'eat' of undefined
。
最后,我完成了一个实现,但并不完美。
function Man(name) {
console.log(`Hello, I am ${name}`)
this.jobs = []
this.ms = 0
}
Man.prototype.sleep = function(ms) {
this.ms += ms
setTimeout(() => {
this.next()
}, this.ms * 1000)
return this
}
Man.prototype.eat = function(food) {
this.jobs.push(function() {
console.log(`Eat ${food}`)
})
return this
}
Man.prototype.jump = function() {
this.jobs.push(function() {
console.log('Jumping...')
})
return this
}
Man.prototype.next = function() {
const job = this.jobs.shift()
if (typeof job === 'function') job.call(this)
}
new Man('Tom').sleep(3).eat('dinner').sleep(4).jump()
// output: 'Hello, I am Tom'
// After 3 seconds
// output: 'Eat dinner'
// After 4 seconds
// output: 'Jumping...'
期待更好的实现。
这里有另一个解决方案:
const jobs = []
const next = function() {
const job = jobs.shift()
if (typeof job === 'function') job()
}
function Man(name) {
console.log(`Hello, I am ${name}`)
setTimeout(() => {
next()
}, 30)
return {
sleep: function(t) {
jobs.push(function() {
setTimeout(function() {
next()
}, t * 1e3)
})
return this
},
eat: function(food) {
jobs.push(function() {
console.log(`Eat ${food}`)
next()
})
return this
},
jump: function() {
jobs.push(function() {
console.log('Jumping...')
next()
})
return this
}
}
}
Man('Tom').sleep(3).eat('dinner').sleep(4).jump()