我正在通过将各种 Java 程序移植到 Dart 并比较和分析结果来为一家德国公司评估 Dart。在浏览器中,Dart 胜出。服务器软件性能似乎是一个严重的问题(参见 this question of me ),但大部分都被解决了。
现在我正在移植一些“简单”的命令行工具,我没想到会出现任何严重的问题,但至少有一个。一些工具确实会发出 HTTP 请求来收集一些数据,而独立的 Dart 虚拟机仅以异步方式支持它们。查看所有我能找到的内容,似乎不可能在一个主要是同步的软件中使用任何异步调用。
我知道我可以将可用的同步软件重组为异步软件。但这会将精心设计的软件变成可读性较差且更难以调试和维护的软件。对于某些软件而言,这毫无意义。
我的问题:是否有一种(被我忽略的)方法可以将异步调用嵌入到同步调用的方法中?
我想提供一个系统调用并不难,它只能在主线程中使用,它只是将执行转移到整个排队的异步函数调用列表(无需先结束主线程)并且尽快随着最后一个被执行返回并继续主线程。
可能看起来像这样的东西:
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 调用封装为同步调用是不可能的。它一直在“正常”同步编程世界中完成。通常,您可以通过从异步例程中获取“完成”或者在超时后继续执行某些操作来等待重新同步。考虑到这一点,我的第一个建议可以像这样增强:
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()
返回主线程。如果没有 continueResync()
在给定的 timeout
期间遇到调用期间它也会中止异步执行并离开 resync()
与 TimeoutException
.对于某些受益于直接同步编程(不是客户端软件和服务器软件)的软件组,这样的功能将为必须处理仅异步库的程序员解决很多问题。
我相信我也在
lm
中找到了主要论点的解决方案。的论证如下。因此,对于我提出的这个“增强”解决方案,我的问题仍然存在:有什么东西真的让 Dart 无法实现它吗?
最佳答案
唯一可以将异步方法包装在同步方法中的时间是不需要获取返回值的时候。
例如,如果您想禁用保存按钮,将结果异步保存到服务器并在工作完成后重新启用保存按钮,您可以这样编写:
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
方法异步。请注意,如果您制作
saveClicked
async,您不仅必须使用 async 模式调用它,而且整个方法主体将异步运行,因此在函数返回时不会禁用保存按钮。为了完整起见,
saveClicked
的异步版本看起来像这样: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;
}
}
关于asynchronous - 如何使异步 Dart 调用同步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28238161/