如何使异步Dart调用同步? [英] How to make an asynchronous Dart call synchronous?

查看:677
本文介绍了如何使异步Dart调用同步?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过将各种Java程序移植到Dart并比较和分析结果的方式来评估一家德国公司的Dart.在浏览器中,Dart胜出.对于服务器软件而言,性能似乎是一个严重的问题(请参阅

I'm on the way to evaluate Dart for a German company by porting various Java programs to Dart and compare and analyze the results. In the browser Dart wins hands down. For server software performance seemed to be a serious isssue (see this question of me) but that got mostly defused.

现在,我正在移植一些简单"的命令行工具,我根本没想到会遇到任何严重的问题,但至少有一个.有些工具会发出HTTP请求以收集一些数据,而独立的Dart虚拟机仅以异步方式支持它们.仔细研究一下,我发现似乎无法在大多数为同步的软件中使用任何异步调用.

Now I'm in the area of porting some "simple" command-line tools where I did not expect any serious problems at all but there is at least one. Some of the tools do make HTTP requests to collect some data and the stand-alone Dart virtual machine only supports them in an asynchronous fashion. Looking through all I could find it does not seem to be possible to use any asynchronous call in a mostly synchronous software.

我知道我可以将可用的同步软件重组为异步软件.但是,这会将精心设计的软件转变为可读性差,调试和维护困难的软件.对于某些软件而言,这根本没有意义. 我的问题:是否有一种(被我忽略)将异步调用嵌入到同步调用的方法中的方法?

I understand that I could restructure the available synchronous software into an asynchronous one. But this would transform a well-designed piece of software into something less readable and more difficult to debug and maintain. For some software pieces this just does not make sense. My question: Is there an (overlooked by me) way to embed an asynchronous call into a synchronously called method?

我想提供一个仅在主线程中可用的系统调用并不困难,它只需将执行转移到排队的异步函数调用的整个列表中(而不必先结束主线程)最后一个执行后,返回并继续执行主线程.

I imagine that it would not be to difficult to provide a system call, usable only from within the main thread, which just transfers the execution to the whole list of queued asynchronous function calls (without having to end the main thread first) and as soon as the last one got executed returns and continues the main thread.

可能看起来像这样的东西

Something which might look like this:

var synchFunction() {
  var result;
  asyncFunction().then(() { result = ...; });

  resync(); // the system call to move to and wait out all async execution

  return result;
}

拥有这种方法还将简化lib API.可以删除大多数同步"调用,因为重新同步调用可以完成这项工作.这似乎是一个合乎逻辑的想法,我仍然认为它以某种方式存在并且我已经错过了.还是有一个严重的原因为什么不起作用?


在考虑了从lm收到的答案(请参阅下文)两天后,我仍然不明白为什么不能将异步Dart调用封装为同步调用.它总是在正常"的同步编程环境中完成.通常,您可以通过从异步例程中获取完成"来等待重新同步,或者如果超时后仍然失败,则可以等待重新同步.

Having such a method would simplify the lib APIs as well. Most "sync" calls could be removed because the re-synchronisation call would do the job. It seems to be such a logical idea that I still think it somehow exists and I have missed it. Or is there a serious reason why that would not work?


After thinking about the received answer from lm (see below) for two days I still do not understand why the encapsulation of an asynchronous Dart call into a synchronous one should not be possible. It is done in the "normal" synchronous programing world all the time. Usually you can wait for a resynchronization by either getting a "Done" from the asynchronous routine or if something fails continue after a timeout.

考虑到这一点,我的第一个建议可以这样进行增强:

With that in mind my first proposal could be enhanced like that:

var synchFunction() {
  var result;
  asyncFunction()
    .then(() { result = ...; })
    .whenComplete(() { continueResync() }); // the "Done" message

  resync(timeout); // waiting with a timeout as maximum limit

  // Either we arrive here with the [result] filled in or a with a [TimeoutException].
  return result;
}

resync()的行为与结束隔离的main方法后通常会发生的事情相同,它开始执行排队的异步函数(或等待事件使它们可执行).一旦遇到continueResync()调用,就会设置一个标志,该标志将停止此异步执行,并且resync()返回主线程.如果在给定的timeout期间未遇到continueResync()调用,它也会中止异步执行,并留下resync()并带有TimeoutException.

The resync() does the same that would normally happen after ending the main method of an isolate, it starts executing the queued asynchronous functions (or waits for events to make them executable). As soon as it encounters a continueResync() call a flag is set which stops this asynchronous execution and resync() returns to the main thread. If no continueResync() call is encountered during the given timeout period it too aborts the asynchronous execution and leaves resync() with a TimeoutException.

对于某些受益于直接同步编程的软件组(不是客户端软件,而不是服务器软件),此功能将为不得不处理纯异步库的程序员解决很多问题.

For some groups of software which benefit from straight synchronous programing (not the client software and not the server software) such a feature would solve lots of problems for the programer who has to deal with asynchrounous-only libraries.

我相信我也在下面的lm的论点中找到了针对主要论点的解决方案.因此,对于我提出的这种增强型"解决方案,我的问题仍然存在:真的有什么东西真的不可能在Dart中实现吗?

I believe that I have also found a solution for the main argument in lm's argumentation below. Therefore my question still stands with respect to this "enhanced" solution which I proposed: Is there anything which really makes it impossible to implement that in Dart?

推荐答案

唯一可以将异步方法包装在同步方法中的时间是不需要获取返回值的时候.

The only time that you can wrap an async method in a synchronous one is when you don't need to get a return value.

例如,如果要禁用保存"按钮,将结果异步保存到服务器,并在作业完成后重新启用保存"按钮,则可以这样编写:

For example if you want to disable the save button, save results to the server asynchronously and re-enable the save button when the job is done you can write it like this:

Future<bool> save() async {
  // save changes async here
  return true;
}

void saveClicked() {
  saveButton.enabled = false;
  save()
    .then((success) => window.alert(success ? 'Saved' : 'Failed'))
    .catchError((e) => window.alert(e))
    .whenComplete(() { saveButton.enabled = true; });
}

请注意,saveClicked方法是完全同步的,但是异步执行save方法.

Note that the saveClicked method is fully synchronous, but executes the save method asynchronously.

请注意,如果使saveClicked异步,则不仅需要使用异步模式来调用它,而且整个方法主体都将异步运行,因此在函数返回时不会禁用保存按钮.

Note that if you make saveClicked async, not only do you have to call it using the async pattern, but the entire method body will run asynchronously so the save button will not be disabled when the function returns.

出于完整性考虑,saveClicked的异步版本如下:

For completeness the async version of saveClicked looks like this:

Future<Null> saveClicked() async {
  saveButton.enabled = false;
  try {
    bool success = await save();
    window.alert(success ? 'Saved' : 'Failed');
  }
  catch (e) {
    window.alert(e);
  }
  finally {
    saveButton.enabled = true;
  }
}

这篇关于如何使异步Dart调用同步?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆