dart - Dart异步执行其他操作然后等待

标签 dart angular-dart

我已经阅读了几个stackoverflow问题,dart文档,甚至还观看了有关异步和等待的视频。我没有找到问题的答案。我想调用一个异步方法,执行其他代码,然后等待异步任务完成。

这是我正在使用的示例。这是我的组成部分

Credit credit;
...
Future<Null> getCredit(id) async {
  try {
    credit = await _creditService.getCredit(id);
  }
  catch (e) {
    errorMessage = e.toString();
  }
}
...
void onUpdateCredit(int credit_id) {
  getCredit(credit_id);
  creditDialogTitle = 'Update Credit';
  creditArtistIndex = credit.artist_id;
  instrument = credit.instrument;
  creditNotes = credit.notes;
  creditDialog.open();
}

此代码崩溃,因为尝试使用信用时信用为空。解决它的一种方法是将两种方法结合起来:
Future<Null> onUpdateCredit(id) async {
  try {
    credit = await _creditService.getCredit(id);
    creditDialogTitle = 'Update Credit';
    creditArtistIndex = credit.artist_id;
    instrument = credit.instrument;
    creditNotes = credit.notes;
    creditDialog.open();
  }
  catch (e) {
    errorMessage = e.toString();
  }
}

没有任何事情是并行的,并且,如果我在代码中的其他地方需要帮助,我将不得不复制该方法的try / catch部分。我也可以这样编码:
void onUpdateCredit(int credit_id) {
  credit = null;
  getCredit(credit_id);
  creditDialogTitle = 'Update Credit';
  while (credit == null) {//wait a period of time}
  creditArtistIndex = credit.artist_id;
  instrument = credit.instrument;
  creditNotes = credit.notes;
  creditDialog.open();
}

在其他情况下,我使用* ngIf =“var!= null”在html中执行类似操作,其中var由将来填充。

有没有比while(credit == null)更好的方法?这个例子只在请求和完成之间执行一条指令,所以很简单。我敢肯定,在其他情况下,我之间还有很多事情要做。我还添加了服务方法:
Future<Credit> getCredit(int id) async {
  try {
    String url = "http://catbox.loc/credits/${id.toString()}";
    HttpRequest response = await HttpRequest.request(
        url, requestHeaders: headers);
    Map data = JSON.decode(response.responseText);
    final credit = new Credit.fromJson(data);
    return credit;
  }
  catch (e) {
    throw _handleError(e);
  }
}

更新资料

基于@Douglas的答案,这可行:
Future<Null> onUpdateCredit(id) async {
  Future future = getCredit(id);
  creditDialogTitle = 'Update Credit';
  await future;
  creditArtistIndex = credit.artist_id;
  instrument = credit.instrument;
  creditNotes = credit.notes;
  creditDialog.open();
}

然后,我消除了干预方法。
Future<Null> onUpdateCredit(id) async {
  try {
    Future<Credit> future =  _creditService.getCredit(id);
    creditDialogTitle = 'Update Credit';
    credit = await future;
    creditArtistIndex = credit.artist_id;
    instrument = credit.instrument;
    creditNotes = credit.notes;
    creditDialog.open();
  }
  catch (e) {
    errorMessage = e.toString();
    }
}

最佳答案

getCredit(credit_id)不仅会启动异步调用,还会立即返回Future对象。将该对象存储在局部变量中,以后可以使用它在完成时异步执行其他代码。

有两种使用Future对象的方法。更简单,更流畅的方法要求您将onUpdateCredit声明为async。在async函数内部,await futureObject行将导致Future完成后异步执行该行之后的所有代码。使用此技术的onUpdateCredit的完整版本如下所示:

Future<Null> onUpdateCredit(int credit_id) async {
  Future future = getCredit(credit_id);
  creditDialogTitle = 'Update Credit';
  await future;
  creditArtistIndex = credit.artist_id;
  instrument = credit.instrument;
  creditNotes = credit.notes;
  creditDialog.open();
}

另一种方法是使用.then()将其余的代码显式注册为回调。看起来像这样:
void onUpdateCredit(int credit_id) {
  Future future = getCredit(credit_id);
  creditDialogTitle = 'Update Credit';
  future.then((_) => {
    creditArtistIndex = credit.artist_id;
    instrument = credit.instrument;
    creditNotes = credit.notes;
    creditDialog.open();
  });
}

请注意,无论哪种情况,如果getCredit(id)中都出现了异常路径,则会因未设置credit而出现错误。如果您确实希望默默地吞下该异常,则应让其处理程序填写credit的默认值,以便假定该异常正常完成的代码仍然可以使用。

另请注意,您的while循环版本将失败-Dart(如JavaScript)不是真正的多线程,并且像这样的繁忙等待将永远阻止事件循环,从而阻止设置credit的代码永远运行。

关于asyncawait总体工作原理的简短摘要:
Future someFunc(args) async {
  ...
  return value;
}

等效于:
Future someFunc(args) {
  return new Future(() => {
    ...
    return value;
  }
}

内部的代码在事件循环的后续迭代中执行,并且返回的future可以通过value成功完成,也可以通过该代码中抛出的异常完成。

同时这:
try {
  value = await someFutureObject;
  ...more code here...
} catch (e) {
  ...exception handling here...
}

等效于:
someFutureObject.then((value) => {
  ...more code here...
}).catchError((e) => {
  ...exception handling here...
});

最常见的用例是someVar = await someAsyncCall();,但是您可以通过省略Future来保存await本身,或者可以将await放在任意Future对象上,无论它来自哪里。

但是-这就是awaitasync如此便捷的原因-您可以在13个嵌套循环,开关,try / catch中的各个位置中,从async函数中散布5个不同的退出点,并在三个不同的await调用中(在同一个async中)和if块,Dart会自动找出必要的回调树,使其全部遵循相同的代码路径,就好像所有调用都是同步的一样。

关于dart - Dart异步执行其他操作然后等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39604857/

相关文章:

android - Flutter - 如何在 `snackbar` 中显示 `Future`

angularjs - Angular Dart 和表单验证

dart - 连接 2 个 Controller 并可以访问第二个 Controller 中的第一个 Controller 属性

flutter - Flutter PageView删除页面指示器

flutter - 在 Dart 中抛出异常的性能成本是多少?

javascript - 无法在 flutter webview 中打开 tel、mailto、whatsapp 链接?

namespaces - 角达特 : Namespace of route names hierarchical too?

dart - 没有定义方法的 forEach() 迭代

dart - 组件属性为无-计时问题

dart - PolymerDart 死了吗?一个架构问题