【问题标题】:Rxjs: How to implement Observable.first()?Rxjs:如何实现 Observable.first()?
【发布时间】:2017-11-12 16:05:25
【问题描述】:

我正在学习 RxJs 并试图了解 Observable.first() 方法是如何工作的。 Source code 很乱。

有没有一种简单的方法来实现这个方法来理解它是如何工作的?

我想确切地了解它在内部是如何工作的,而不是如何实现它。

【问题讨论】:

    标签: rxjs observable


    【解决方案1】:

    从我们看到的文档中

    只发出第一个值。或者只发出通过某些测试的第一个值。

    因此,基本行为(仅发出第一个值)是通过使用订阅者级字段跟踪第一个值是否已发出来完成的。

    那么predicateresultSelectordefaultValues 只是对该基本代码的一点补充(基本上是filtermapdefault)。

    如果你想看一下这个操作符的具体代码,相关部分是FirstSubscriber._next => FirstSubscriber._emit => FirstSubscriber._emitFinal,它使用this._emitted标志来跟踪它是否已经发出。

    编辑:如果您想定义一个自定义 Rx 扩展,它可以在不使用其他基本运算符(例如 take(1))的情况下完成 first() 所做的事情,我会这样做:

    Observable.prototype.first = function() {
        const source = this;
        return new Observable(observer => {
            let hasSentValue = false;
    
            return source.subscribe(
                v => {
                    if(!hasSentValue) {
                        observer.next(v);
                        observer.complete();
                        hasSentValue = true;
                    }
                },
                err => observer.error(err),
                () => {
                    if(!hasSentValue) {
                        observer.error("Empty stream");
                    }
                });
        });
    };
    

    注意:未测试

    【讨论】:

    • “到那个基本代码”你能在这里提供基本代码吗?
    • @StepanSuvorov 我不完全明白你在这里问什么。 “基本代码”不是指简单/简短,而是涵盖.first() 基本行为的代码。如果你想看看它是如何实现的(你现在要求代码),我已经向你指出了 Rx repo 中的相关部分(FirstSubscriber._next => FirstSubscriber._emit => FirstSubscriber._emitFinal
    • 我添加了一些代码来简化该仓库的内容。它应该给你一个想法......
    猜你喜欢
    • 1970-01-01
    • 2017-10-12
    • 2018-07-12
    • 1970-01-01
    • 2021-09-08
    • 2020-07-30
    • 2018-09-08
    • 1970-01-01
    • 2017-06-12
    相关资源
    最近更新 更多