重试后怎么抓?

时间:2017-04-17 12:20:53

标签: javascript angular rxjs observable

如果出现错误,我想在第二次延迟时重试get几次请求,但如果所有尝试失败,则执行错误处理程序。

以下代码重试请求,但catch永远不会执行。我该如何解决?

import {Response, Http} from '@angular/http';
import {Observable} from 'rxjs/Rx';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
this.http.get("/api/getData").map(data => {
  console.log('get')
  return data.json()
})
.retryWhen(err => {
  console.log('retry')
  return err.delay(1000).take(5)
})
.catch(err => {
  console.log('catch')
  this.handleHttpError(err)
  return err
})
.subscribe(data => {
  console.log('subscribe')
  console.log(data)
})

3 个答案:

答案 0 :(得分:6)

这里的问题是,当Bar中的回调回复通知Observable发送retryWhen通知时,它会进一步传播为complete,这不是您想要的你的描述。

您希望将其作为complete通知发送,这意味着您无法使用error并使用其他运算符来重新抛出错误。

例如:

take()

您可以自己计算Observable.defer(() => Observable.throw("It's broken")) .retryWhen(err => { console.log('retry'); let retries = 0; return err .delay(1000) .map(error => { if (retries++ === 5) { throw error; } return error; }); }) .catch(err => { console.log('catch'); return Observable.of(err); }) .subscribe(data => { console.log('subscribe'); console.log(data); }); 变量中的重试次数,如果达到某个限制,只需重新抛出错误。 retries运算符用try-catch块包装所有回调,因此在其callable中抛出的任何错误都将作为map()信号发送。

答案 1 :(得分:2)

return err.delay(1000).take(5)

重试后应该出错,例如:

return err.delay(1000).take(5).concat(Observable.throw(err))

感谢@martin指出此代码实际上抛出了Observable而不是错误。

答案 2 :(得分:0)

将现代rxjs与pipe配合使用,将在retryWhen运算符中返回的可观察对象通过某种逻辑传递给逻辑,如果满足特定条件,该逻辑将引发错误。

https://stackblitz.com/edit/rxjs-retrywhen-to-catch

import { interval, of, throwError, timer } from 'rxjs'; 
import { catchError, mergeMap, switchMap, retryWhen, tap } from 'rxjs/operators';

const source = interval(1000);

const example = source.pipe(
  // simulate error
  switchMap(count => count > 3
    // this will be caught by retryWhen
    ? throwError('Error from source!')
    : of(count)
  ),
  retryWhen(err$ => err$.pipe(
    // display error from source
    tap(console.error),
    // i === index, AKA how many tries
    mergeMap((err, i) => i > 1
      // throw error, which is caught by catchError
      // or second argument to subscribe function if catchError not used
      ? throwError('Error from retry!')
      // wait specified duration before retrying
      : timer(3000)
    )
  )),
  catchError(err => of('There was an error, but we handled it. '))
);

example.subscribe(
  console.log,
  () => console.error('Nothing reaches this error handler because we used catchError')
);

/*

RESULT
0
1
2
3
Error from source!
0
1
2
3
Error from source!
0
1
2
3
Error from source!
There was an error, but we handled it. 

*/

受到this solution from learn-rxjs

的启发