Трубка RxJS без молнии

Я заархивирую три наблюдаемых объекта, у каждой из трех наблюдаемых есть собственный обратный вызов "успеха" с использованием .pipe(tap() => {...});. Это отлично работает, когда все три наблюдаемых объекта выполняются без ошибок, но если одна из наблюдаемых ошибок выдает ошибку, то ни один из методов касания не выполняется. Как я могу всегда выполнять методы касания, если эта наблюдаемая работает успешно?

var request1 = Observable.create(...);  //Pretend this one will fail (though request2 or request3 could also fail)
var request2 = Observable.create(...);
var request3 = Observable.create(...);

request1.pipe(tap(() => {
    //Unique success callback should always run if request1 succeeds, even if request2 or request 3 fails.
}));

request2.pipe(tap(() => {
    //Unique success callback should always run if request2 succeeds, even if request1 or request 3 fails.
}));

request3.pipe(tap(() => {
    //Unique success callback should always run if request3 succeeds, even if request1 or request 2 fails.
}));

var observable = zip(request1, request2, request3);
observable.subscribe(() => {
    //Do something when all three execute successfully
});

person Community    schedule 01.06.2018    source источник
comment
как это связано с angular?   -  person Jota.Toledo    schedule 01.06.2018
comment
@ Jota.Toledo Вы проголосовали против, потому что в моем примере я использовал Observable.create вместо httpClient.post?   -  person    schedule 01.06.2018


Ответы (3)


Я считаю, что это ожидаемое и подходящее поведение для того, с чем вы имеете дело. Вероятно, вы захотите использовать конвейерную привязку catchError lettable к каждому из ваших запросов и возвращение пустого наблюдаемого объекта.

request1.pipe(tap(() => {
    //Unique success callback
}), catchError((err) => {
    return empty();
}));

Таким образом вы справитесь с ошибкой наблюдаемого объекта, не нарушая новый zip.

person MichaelSolati    schedule 01.06.2018
comment
Спасибо за отзыв, хотя я не думаю, что это то, что я ищу. Я обновил свои комментарии выше для разъяснения. - person ; 01.06.2018

Добавьте catch блок в свой код, где вы можете отслеживать ошибки.

request1.pipe(tap(() => {
    //Unique success callback I want to run if request2 succeeds.
    //It should still run if request1 fails
}),
    catchError(// Error occured)
);
person Amit Chigadani    schedule 01.06.2018
comment
Спасибо за отзыв, хотя я не думаю, что это то, что я ищу. Я обновил свои комментарии выше для разъяснения. - person ; 01.06.2018

@MichaelSolati почти прав, за исключением

  • вы должны поймать и вернуть значение, например null, если вы хотите видеть результат в subscribe(), потому что zip не запускается с empty()
  • ваши tap() обратные вызовы не находятся в zip() конвейере, это отдельные ветки, на которые не подписана подписка, поэтому они никогда не активируются.

Обратите внимание, что с изменениями в версиях rxjs импорт может стать немного сложным, например, zip доступен как функция и как оператор.
С rxjs.umd.js cdn, использованным в приведенном ниже фрагменте, я изначально использовал оператор по ошибке и это не вызывает ошибки (но не работает).

Я заметил из комментариев выше, что вы делаете это в контексте Angular. Если у вас все еще есть проблема, опубликуйте свой полный модуль Angular с импортом, и мы сможем решить проблему.

console.clear()
//console.log(rxjs)

// Get the operators and creators
const tap = rxjs.operators.tap
const empty = rxjs.empty
const zip = rxjs.zip
const catchError = rxjs.operators.catchError
const of = rxjs.of
const throwError = rxjs.throwError


//var request1 = of(1)
var request1 = throwError('error') 
var request2 = of(2)
var request3 = of(3)

var req1 = request1.pipe(
  tap(() => console.log('request1')),
  catchError((err) => { 
    console.log('request1 has error')
    return of(null) 
  })
);

var req2 = request2.pipe(
  tap(() => { console.log('request2');})
);

var req3 = request3.pipe(
  tap(() => { console.log('request3');})
);

var myObservable = rxjs.zip(req1, req2, req3);
myObservable.subscribe(
  result => { console.log('result', result) }
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.2.0/rxjs.umd.js"></script>

person Richard Matsen    schedule 03.06.2018