Future.error和投掷飞镖Future有什么区别?

时间:2019-10-14 18:01:51

标签: asynchronous dart future

我想了解何时在异步函数中使用throwreturn Future.error。选择一个或另一个时,我们应该考虑任何潜在的差异吗?

我做了一个小测试:

Future testFuture() async {
  return Future.error('error from future');
}

void testThrow() {
  throw('error from throw');
}


Future testFutureThrow() async {
  throw('error from future throw');
}

main() async {
  print('will run test');

  try{
    await testFuture();
  }
  catch(e){
    print(e);
  }

  try{
    testThrow();
  }
  catch(e){
    print(e);
  }


  try{
    await testFutureThrow();
  }
  catch(e){
    print(e);
  }


  testFuture().catchError((e) => print(e));
  testFutureThrow().catchError((e) => print(e));

  print('did run test');
}

它们似乎都以相同的方式工作。这是输出:

will run test
error from future
error from throw
error from future throw
did run test
error from future
error from future throw

从此测试中我们可以看到,从调用者的角度来看,当使用try/catch调用函数时,代码是同步运行的;如果我们Future.catchError是异步的,则代码将同步运行。但是从功能流程的角度来看,它似乎是相同的。

  

注意:我起初是为了回答问题。但是后来我意识到我不是在回答而是在提问。

2 个答案:

答案 0 :(得分:0)

我的经验是,如果您想使用myFunc().then(processValue).catchError(handleError);,则应该返回Future.error而不是抛出它。

答案 1 :(得分:0)

异步等待是一种语言扩展/语法糖,可以通过恢复同步方式来简化异步代码的使用。

两者都直接取消了期货的使用,使此代码类似:

  // On the callee's side
  Future<String> calleeAsync() async {
    return "from async callee";
  }

  Future<String> calleeSync() {
    return Future.value("from sync callee");
  }
  // On the caller's side
  Future<void> callerAsync() async {
    print("got ${await calleeAsync()}");
    print("got ${await calleeSync()}");
  }

  void callerSync() {
    calleeAsync()
        .then((v) => print("got3 $v"))
        .then((_) => calleeSync())
        .then((v) => print("got4 $v"));
  }

(在callerSync中,第二个then()的回调可以与第一个回调合并,而第三个then()也可以由于与monad类似的关联而直接附加到calleeSync()上)

以相同的方式,这些功能是等效的:

  // On the callee's side
  Future<void> calleeAsync() async {
    throw "error from async";
  }

  Future<void> calleeSync() {
    return Future.error("error from sync");
  }
  // On the caller's side
  Future<void> callerAsync() async {
    try {
      await calleeAsync();
    } catch (e) {
      print("caught $e");
    }
    try {
      await calleeSync();
    } catch (e) {
      print("caught $e");
    }
  }

  void callerSync() {
    calleeAsync()
        .catchError((e) => print("caught $e"))
        .then((_) => calleeSync())
        .catchError((e) => print("caught $e"));
  }

总而言之,没有实际区别。 return Future.error(…)根本没有利用 async 函数提供的扩展,因此更像是将两种异步代码混合在一起。