RXJS: Adding a function to Observable to execute when subscribed to (defer)

牧云@^-^@ 提交于 2019-12-12 09:56:59

问题


Adding a function to Observable to execute when subscribed to (defer)

I have an Observable made from events. In this case, Bluetooth notifications.

I want to run a function (startNotifictions) only when someone is subscribing to that Observable.

This code did work, on previous versions. It is with Ionic3 framework. It added a new operator, that ran when subscribed. Now the transpiler has a problem with the types, complaining twice, that the .doOnSubscribe is not available on typedef Observable any> and <{}>.

Anyone has an idea how to get that typed correctly? Extend maybe? Tried to use .defer directly, no avail.

 // add operator doOnSubscribe to the event observable
        Observable.prototype.doOnSubscribe = function(onSubscribe) {
            let source = this;
            return Observable.defer(() => {
                onSubscribe();
                return source;
            });
        };

        // return the Observable for the notify char, with startNotify on first subscribe
        getUartDataNote( Observable.fromEvent( this.uartChar, 'characteristicvaluechanged' )
            .doOnSubscribe(() => {
                console.log('starting note');
                this.uartChar.startNotifications();
            })
            .map( value => String.fromCharCode.apply( null, new Uint8Array( this.uartChar.value.buffer )))
            .takeUntil( Observable.fromEvent( this.gatt.device, 'gattserverdisconnected' ))
            .finally(() => {
                console.log( 'stream disconnected ');
                // not necessary: return this.uartChar.stopNotifications()
            })
            .share()
        );

回答1:


Here is how you write the type augmentation.

export {}

declare module 'rxjs/Observable' {
  interface Observable<T> {
    doOnSubscribe(onSubscribe: () => void): this;
  }
}

This is documented in the Declaration Merging section of the TypeScript handbook.




回答2:


If you're using rxjs version 5, you can implement doOnSubscribe using pure functions instead of patching the prototype. This way you won't need the type augmentation.

import {defer} from 'rxjs/observable/defer';
import {Observable} from 'rxjs/Observable';

/** Example
import {from} from 'rxjs/observable/from';

from([1, 2, 3])
    .pipe(doOnSubscribe(() => console.log('subscribed to stream')))
    .subscribe(x => console.log(x), null, () => console.log('completed'));
*/

export function doOnSubscribe<T>(onSubscribe: () => void): (source: Observable<T>) =>  Observable<T> {
    return function inner(source: Observable<T>): Observable<T> {
        return defer(() => {
          onSubscribe();

          return source;
        });
    };
}

https://gist.github.com/evxn/750702f7c8e8d5a32c7b53167fe14d8d



来源:https://stackoverflow.com/questions/46881510/rxjs-adding-a-function-to-observable-to-execute-when-subscribed-to-defer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!