Dart中的catchError捕获顺序

先贴一下该方法的源码:

  /**
   * Handles errors emitted by this [Future].
   *
   * This is the asynchronous equivalent of a "catch" block.
   *
   * Returns a new [Future] that will be completed with either the result of
   * this future or the result of calling the `onError` callback.
   *
   * If this future completes with a value,
   * the returned future completes with the same value.
   *
   * If this future completes with an error,
   * then [test] is first called with the error value.
   *
   * If `test` returns false, the exception is not handled by this `catchError`,
   * and the returned future completes with the same error and stack trace
   * as this future.
   *
   * If `test` returns `true`,
   * [onError] is called with the error and possibly stack trace,
   * and the returned future is completed with the result of this call
   * in exactly the same way as for [then]'s `onError`.
   *
   * If `test` is omitted, it defaults to a function that always returns true.
   * The `test` function should not throw, but if it does, it is handled as
   * if the `onError` function had thrown.
   *
   * Note that futures don't delay reporting of errors until listeners are
   * added. If the first `catchError` (or `then`) call happens after this future
   * has completed with an error then the error is reported as unhandled error.
   * See the description on [Future].
   */
  // The `Function` below stands for one of two types:
  // - (dynamic) -> FutureOr
  // - (dynamic, StackTrace) -> FutureOr
  // Given that there is a `test` function that is usually used to do an
  // `isCheck` we should also expect functions that take a specific argument.
  // Note: making `catchError` return a `Future` in non-strong mode could be
  // a breaking change.
  Future catchError(Function onError, {bool test(Object error)});

翻译一下主要的意思,就是这个catchError方法可以捕获其他Futrue的异常信息,如果重写了test方法,test返回true就可以在catchError的onError方法里捕获到异常,如果test返回false,就把该异常继续抛出而不会在catchError方法里被捕获,如果不写test默认实现一个返回true的test方法,注意catchError只能捕获Future的异常,而不能捕获同步代码的异常,测试代码如下:

import 'dart:async';

Future testFutureError() {
  return new Future(() {
    throw "error";//1
//    return "abc";//2
  });
}

main() {
  testFutureError().then((value) {
    print("then " + value);
  }).catchError((e) {
    print("catchError " + e);
  }, test: (Object o) {
    print("test " + o);
    return true;//3
//    return false;//4
  }).catchError((e) {
    print("catchError2 " + e);
  }, test: (_) => true);
}

如果是上面的代码,会输出

test error
catchError error

因为//3这行返回了true,所以会在第一个catchError里被捕获。
如果//4不注释了,把//3注释,那么第一个catchError不能捕获该异常,该异常会继续抛出,然后在第二个catchError里被捕获。具体的可自行测试。

还有就是用whenComplete方法的时候,不是所有then都执行完再执行whenComplete方法,而是then、catchError、whenComplete这些方法会按照顺序(除非中途有异常会进入下一个catchError)执行,这一点和rxjava+retrofit不一样,原生开发请知悉。

你可能感兴趣的:(Dart中的catchError捕获顺序)