代码之家  ›  专栏  ›  技术社区  ›  roomcayz

有没有办法在同一个变量下有一个可观察的对象

  •  1
  • roomcayz  · 技术社区  · 7 年前

    目前我有这样一个代码:

    const exampleSubject = new Subject<any>();
    const example$ = exampleSubject.pipe(...);
    // later emit some data to that subject and do things with observable, like subscribtion
    

    工作很好,但是有没有办法两者兼得 Subject Observable 在相同的变量/属性下同时转换数据,例如:

    const example$ = (a subject constructor).pipe(...);
    // later execute example$.emit(...), example$.subscribe(...), etc.
    

    你可能会注意到 pipe 运算符总是返回 Observable<T> 这就是问题所在,但也许我缺少了一些功能?

    我宁愿避免制造像这样的小怪物:

    let subscriber: Subscriber<any>;
    const example$ = (new Observable<any>((sub) => { subscriber = sub; })).pipe(...);
    // later calling subscriber.next(...), subscriber.complete(...), etc.
    

    那么,有没有一种方法可以让一个主题和可观察的(使用管道或其他使用操作符的方式)在同一个变量下,仍然从外部发出数据?

    1 回复  |  直到 7 年前
        1
  •  2
  •   Oscar Paz    7 年前

    不,没有。 Subject Observable . pipe 作品与 可观察的 ,所以,当然,它与 主体 也是,但是你得到了 可观察的 不是 主体 作为调用该函数的结果。

    没有必要通过 ,因为,打电话给这样的接线员,你是说你想得到结果 可观察的 成为一股来自源头的转化价值流 可观察的 数据流。我是说,你可以用 map 改变一系列数字并得到它们的平方。将数据“输入”可观察结果的目的是什么?

    const subject = new Subject<number>();
    const squares$ = subject.pipe(map(item => item*item));
    squares$.subscribe(value => console.log(value));
    squares$.next(2); // we get 4 in the console.
    

    您可以通过充当数据运算符的函数来实现这一点:

    const square = (value: number) => value*value;
    const subject = new Subject<number>();
    subject.subscribe(value => console.log(value));
    subject.next(square(2)); // we get 4 in the console.
    

    当然,您可以通过从 主体 接受转换值的函数:

    const transSubject = new TransSubject<number>(value => value*value);
    transSubject.subscribe(value => console.log(value));
    transSubject.next(2); // we get 4 in the console.
    

    基本上,这样的类将在其构造函数中存储一个转换函数数组,然后重写 next 方法,以便在将结果值传递给超类之前按顺序应用转换函数。 下一个 方法。

    当然,这仍然有一个问题,即一旦定义了 TransSubject ,不能返回其他类型。当然你可以定义 TransSubject<T, K> 上课,所以 下一个 next(value: K) subscribe 会被定义为 subscribe({next: (value: T) => any, complete: ...}) ,但会非常复杂。您应该确保构造函数中的函数组合是 K => T . 你可以有这样的东西:

    const sbj = new TransSubject<string, number>((value: number) => value*value, (value: number) => value.toString());
    

    在这种情况下我们会 number => number number => string 所以,结合起来, 数字=>字符串 ,与类型参数匹配。

    然而,正如我所说,用简单的函数和使用正常的观测值来实现这一点会更容易。你甚至可以做一个闭包来简化它:

    const subject = new Subject<string>();
    const next = (value: number) => subject.next((value * value).toString());
    subject.subscribe(value => console.log(value));
    next(1); // logs '1'
    next(2); // logs '4'
    

    但是,当然,你需要两个变量/属性