面试题 LazyMan 的Rxjs实现方式
Posted lalalagq
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面试题 LazyMan 的Rxjs实现方式相关的知识,希望对你有一定的参考价值。
前言
笔者昨天在做某公司的线上笔试题的时候遇到了最后一道关于如何实现LazyMan的试题,题目如下
实现一个LazyMan,可以按照以下方式调用:
LazyMan(“Hank”)输出:
Hi! This is Hank!LazyMan(“Hank”).sleep(10).eat(“dinner”)输出
Hi! This is Hank!
//等待10秒..
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”)输出
//等待5秒
Wake up after 5
Hi This is Hank!
Eat supper
以此类推。
鉴于时间的原因只可惜本人当时并没写出来,我当时脑海里其实看到提意就知道要用到队列、Promise等异步操作。然后我查阅了网上的资料好像关于这个LazyMan的实现方式倒不少,就说明这道题其实蛮有意思的,但大多都是关于Promise或setTimeout的实现,并没有Rxjs的实现方式,所以我就用一些操作符实现了这个LazyMan
class LazyManModel {
queue: { timeout: number, fn: Function }[] = []
constructor() {
setTimeout(() => {
from(this.queue).pipe(
map(e => {
if (e.timeout) return of(e).pipe(delay(e.timeout * 1000));
return of(e)
}),
concatAll()
).subscribe(value => {
value.fn()
})
})
}
sleep(time: number): this {
this.queue.push({
timeout: time,
fn: () => { console.log(`Wake up after ${time}`) }
})
return this
}
eat(foot: string): this {
this.queue.push({
timeout: null,
fn: () => { console.log(`Eat ${foot}~`) }
})
return this
}
sleepFirst(time: number): this {
this.queue.unshift({
timeout: time,
fn: () => { console.log(`Wake up after ${time}`) }
})
return this
}
exported(): (name: string) => this {
return (name): this => {
this.queue.push({
timeout: null,
fn: () => { console.log(`Hi! This is ${name}!`) }
})
return this
}
}
}
示例
const LazyMan = new LazyManModel().exported();
LazyMan('Hank').eat('foot').eat('ping').sleep(10).eat('pizza').sleepFirst(5)
关于setTimeout
我在constructor构造函数里使用了setTimeout是因为,在调用的时候是链式的,其作用域一直都在同一堆栈,而setTimeout里则是把订阅的方法放到的最后一个栈执行
来源:https://segmentfault.com/a/1190000017842510
以上是关于面试题 LazyMan 的Rxjs实现方式的主要内容,如果未能解决你的问题,请参考以下文章
[RxJS] Implement RxJS `mergeMap` through inner Observables to Subscribe and Pass Values Through(代码片段
[RxJS] Implement RxJS `switchMap` by Canceling Inner Subscriptions as Values are Passed Through(代码片段