面试题 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

原文地址:https://www.cnblogs.com/lalalagq/p/10254751.html

时间: 2024-11-13 08:01:44

面试题 LazyMan 的Rxjs实现方式的相关文章

Python之美[从菜鸟到高手]--读"一道面试题看 HashMap 的存储方式"的联想

今天在伯乐在线 上看到一篇文章,一道面试题看 HashMap 的存储方式,也就是问: 在 HashMap 中存放的一系列键值对,其中键为某个我们自定义的类型.放入 HashMap 后,我们在外部把某一个 key 的属性进行更改,然后我们再用这个 key 从 HashMap 里取出元素,这时候 HashMap 会返回什么? 如何面试者直接答"这要看自定义类型的hash值了",我想面试官会非常满意. 联想到python中dict的实现,python中字典一般不存在这个问题,因为key的ha

面试题-lazyMan实现

原文:如何实现一个LazyMan 面试题目 实现一个LazyMan,可以按照以下方式调用: LazyMan('Hank'),输出: Hi, This is Hank! LazyMan('Hank').sleep(5).eat('dinner'),输出: Hi, This is Hank! // 等待5秒 Weak up after 10 Eat dinner ~ LazyMan('Hank').eat('dinner').eat('supper'),输出 Hi, this is Hank! Ea

.NET面试题(三)

第1讲:面试前期准备 1.了解相关技术职务需要的技术人才                              2.准备一份出色的个人简历 第2讲:面试前期准备                             1. 多渠道获取面试途径                            2.投递简历注意事项                            3. 掌握面试过程…… 第3讲:全面认识.NET框架 1.面试题 介绍CTS.CLS.CLR               

Java创建线程的第二种方式:实现runable接口

/*需求:简单的卖票程序多个窗口买票 创建线程的第二种方式:实现runable接口 *//*步骤1.定义类实现Runable接口2.覆盖Runable接口中的run方法    将线程要运行的代码存放在该run方法中 3.通过Thread类建立线程对象4.将Runable接口的子类对象作为实际参数传递给Thread类的构造函数  为什么要将Runable接口的子类对象传递给Thread的构造函数.  因为,自定义的run方法所属的对象是Runable接口的子类对象  所以要让线程去指定对象的Run

[干货]2020将来,最全面试总结——这些大厂Android “108” 问面试题你一定需要

作为一名即将求职的程序员,面对一个可能跟近些年非常不同的 2019 年,你的就业机会和风口会出现在哪里?在这种新环境下,工作应该选择大厂还是小公司?已有几年工作经验的老兵,又应该如何保持和提升自身竞争力,转被动为主动? 就目前大环境来看,跳槽成功的难度比往年高很多.一个明显的感受:今年的面试,无论一面还是二面,都很考验Android程序员的技术功底. 最近搜集了一些基础问题以及阿里.腾讯2019年一些精选的面试题,最后还把把技术点梳理成一份大而全的"Android高级工程师"面试xmi

阅读《effective java-第17条》遇到的问题解决与分享

问题背景 最近这2天准备重新看一遍<effective java>,发现这些经典的书籍真的是看一遍又有一遍的感受.也越来越觉的学习的过程是一个重复的过程.这次遇到的问题是在第17条中看到的,看了蛮久都没有看懂视例代码.第17条的内容是要么为继承而设计,并提供文档说明,要么就禁止继承.在其中有一段示例构造器决不能调用可被覆盖的方法代码如下: 父类代码 package com.sitech.test; /** * effect of java * @author liaowp * */ publi

JavaSE入门学习5:Java基础语法(一)

一关键字 关键字概述:Java语言中有一些具有特殊用途的词被称为关键字.关键字对Java的编译器有着特殊的意义,在程 序中应用时一定要慎重. 关键字特点:组成关键字的字母全部小写. 关键字注意事项:goto和const作为保留字存在,当前并不使用. Java中常用的50个关键字(48个加2个保留字,就当背英文单词啦): 关键字     描述 abstract    抽象方法,抽象类的修饰符 assert    断言条件是否满足 boolean    布尔数据类型 break    跳出循环或者l

安卓面试备考题收集

最近要参加面试,网上找了一些题来备着,大家也来学习学习吧,话说平时还真有些东西不知道... 面试题一:AIDL的全称是什么?如何工作? Android interface definition language (android接口定义语言) , 用来跨进程的访问方法, 像 游戏中调用支付宝接口就是用的这个. 访问远程的服务的方法. 如何工作. 面试题二:Android程序运行时权限与文件系统权限的区别? 程序运行时权限:Android程序执行需要读取到安全敏感项必需在androidmanife

JavaSE学习总结第03天_Java基础语法2

03.01 数据类型中补充的几个小问题 1:在定义Long或者Float类型变量的时候,要加L或者f.   整数默认是int类型,浮点数默认是double.   byte,short在定义的时候,他们接收的其实是一个int类型的值.  2:数据类型转换之默认转换:byte,short,char→int→long→float→double    为什么占用8个字节的long默认转换为4个字节的float?    A:它们底层的存储结构不同.    B:float表示的数据范围比long的范围要大