наблюдаемые фильтры событий и время ожидания - PullRequest
0 голосов
/ 10 мая 2018

Я очень новый Rxjs, и мне нужна помощь с двумя вопросами. У меня есть этот кусок кода:

const resultPromise = this.service.data
            .filter(response => data.Id === 'dataResponse')
            .filter((response: dataResponseMessage) => response.Values.Success) 
            .take(1)
            .timeout(timeoutInSeconds)
            .map((response: dataResponseMessage) => response.Values.Token)
            .toPromise();

У меня есть следующие основные вопросы:

1 - Как я могу изменить .timeout (timeoutInSeconds), чтобы добавить сообщение, чтобы потом можно было отлаживать / регистрировать, какой ответ не получится? Я посмотрел на синтаксис .timeout в rxjs и не увидел возможности включить какое-либо сообщение или что-то в этом роде.

2-я знаю .filter ((response: dataResponseMessage) => response.Values.Success) будет фильтровать ответы с откликами response.Values.Success, но есть ли синтаксис, в котором я могу сделать это для наблюдаемого:

const resultPromise = this.service.data
                    .filter(response => data.Id === 'dataResponse')
                    .magicSyntax((response: dataResponseMessage) => {
                        if (response.Values.Success) {
                            // do something
                        } else {
                            // do something else
                        }
                    });

Заранее большое спасибо и извините, если это простые / глупые вопросы.

Ответы [ 3 ]

0 голосов
/ 10 мая 2018

1 - вы можете использовать .do () для console.log вашего ответа.

.filter(..).do(response => console.log(response))

2 - вы можете использовать .mergeMap ()

0 голосов
/ 11 мая 2018

Я предполагаю, что вы используете хотя бы Rxjs версии 5.5, в которой введены конвейерные операторы . Из документов - к ним можно "... получить доступ в rxjs / operator (обратите внимание на множественные" операторы "). Они предназначены для того, чтобы лучше подходить для добавления именно тех операторов, которые вам нужны, чем" патч "операторы найдены в rxjs / add / operator /*."

Если вы не используете конвейерные операторы, вместо того, чтобы передавать операторы на pipe(), как я это делал ниже, вы можете объединить их в цепочку, используя обозначение точки, которое вы используете в своем примере.

Я предлагаю обратиться к learnrxjs.io для получения дополнительной информации об операторах в RxJS в сочетании с примерами.

Команда RxJS также создала справочную документацию BETA .

Объяснение

Я предположил, что первый filter получает ответ и фильтрует по ответу. Идентификатор вместо data.Id . Если это не опечатка, фильтр можно оставить прежним.

Я добавил дополнительную строку между операторами только для представления.

mergeMap - это оператор, который принимает функцию, которая возвращает Observable, на который он автоматически подпишется. Я возвращаю of () здесь, что создает Observable, который просто излучает предоставленное ему значение.

catch было переименовано в catchError в RxJS 5.5 , также были добавлены конвейерные операторы, добавляющие поддержку оператора .pipe().

Если вы не хотите ничего делать, кроме регистрации ошибки, вы можете вернуть empty () , что немедленно вызовет complete() для источника Observable, ничего не испуская. EMPTY предпочтительнее, если вы используете версию 6.

Необязательно: Вместо использования filter() и затем take(1), вы можете использовать оператор first () , который возвращает логическое значение, аналогично filter(), и отписывается от источника Наблюдаемый после того, как он возвращает true один раз.

import {EMPTY, of} from 'rxjs';
import {catchError, filter, take, mergeMap, timeout} from 'rxjs/operators';

const resultPromise = service.data.pipe(

    // I assumed you meant response.Id, instead of data.Id
    filter((response: dataResponseMessage) => response.Id === 'dataResponse'),

    take(1),

    // mergeMap accepts a value emitted from the source Observable, and expects an Observable to be returned, which it subscribes to
    mergeMap((response: dataResponseMessage) => {
        if (response.Values.Success) {
            return of('Success!!');
        }
        return of('Not Success');
    }),

    timeout(timeoutInMilliseconds),

    // catch was renamed to catchError in version 5.5.0
    catchError((error) => {
        console.log(error);
        return EMPTY;  // The 'complete' handler will be called. This is a static property on Observable
        // return empty(); might be what you need, depending on version.
    })
).toPromise();
0 голосов
/ 10 мая 2018

Первый вопрос Если вы достигнете тайм-аута, оператор вернет вам ошибку, которую можно поймать с помощью .catch operator

const resultPromise = this.service.data
            .filter(response => data.Id === 'dataResponse')
            .filter((response: dataResponseMessage) => response.Values.Success) 
            .take(1)
            .timeout(timeoutInSeconds)
            .catch(e=>{
              //do your timeout operation here ... 
              return Observable.Of(e)
            })
            .map((response: dataResponseMessage) => response.Values.Token)
            .toPromise();

Второй вопрос - просто замените magicSyntax на map или mergemap, зависит от того, что вы хотите вернуть из этой операции. вполне нормально делать if в стороне блока.

...