我正在考虑使用Dart进行服务器端编程。因为没有类似于Ruby on Rails的完整框架,所以我正在审查更低级别的库。最需要的库是Posgresql驱动程序。我发现很少,最成熟的似乎是https://pub.dartlang.org/packages/postgresql
这是我的问题。 Postgresql驱动程序具有异步API。我知道客户端需要异步API,只是为了不阻止UI线程。但是在服务器端线程可用,所以为什么Postgresql驱动程序有异步API?
我知道Promises API,但对我而言,在服务器端执行操作时,这只是不必要的复杂性。代码可读性是最重要的。
我只是想知道Dart语言设计中是否存在强迫人们构建异步API的东西。所以问题是: Dart是否可以为数据库和文件IO操作同步API?
答案 0 :(得分:3)
Dart库/包可以提供同步API。数据库不倾向于,因为您通常不希望阻止整个服务器等待可能很长的数据库操作完成。例如,假设您正在创建一个Web服务器,其中包含一个请求处理程序,用于从数据库中提取数据并为其提供服务。如果您只使用同步操作,并且您收到了10个请求,其中9个将等待第一个请求完成后再进行处理。
如果你唯一关心的是可读性,你可以等待实现await
关键字,这将有助于你的代码感觉像同步代码,而实际上是异步工作:
var conn = await connect(uri);
var results = await conn.query('select * from users').toList();
for(result in results) {
print("${result.username} has email address ${result.emailAddress}.");
}
答案 1 :(得分:1)
您也需要在服务器上进行并发编程,而不仅仅是在客户端上。服务器一个接一个地处理来自客户端的请求是非常低效的 - 在Dart服务器进程本身等待操作系统,数据库或网络等待开始处理下一个请求之前等待一个请求完全完成完成了对它的调用。
当调用通常为异步的I / O操作时,Dart可以在等待调用的I / O操作完成时开始处理其他请求。
您可以通过使用隔离来改进并发编程,但是您无法创建仅使用同步调用执行某种I / O调用的Dart应用程序。
答案 2 :(得分:1)
Dart不支持多线程,如果不是Dart隔离的形式(但那些不是生产就绪)。只支持异步处理,并且等待"等待"关键字(coroutines的最佳语法)将在未来几个月内添加到Dart中。如果您需要构建一个小型网站,它将非常有用。 但是如果你需要一个真正可扩展的大型网站或苛刻的网络应用程序解决方案,我建议你使用Dart + Go的组合。让Dart管理客户端/ UI端,Golang管理服务器端的数据提供者。由于他的创新" Goroutines" Go是最高性能的语言服务器端。 Goroutines是一种在多个线程中自动运行的形式或协同程序,它将异步处理的灵活性与同步多线程的效率相结合。 Goroutines会自动复用到多个OS线程上,因此如果应该阻塞,例如在等待I / O时,其他线程继续运行。 Go + Dart是一个非常强大的组合。
答案 3 :(得分:1)
Dart确实有同步文件操作。例如,请参阅File.readAsStringSync()。
Dart没有内置方法在套接字上执行阻塞io,这意味着postgresql库必须是异步的。
即使在服务器上,Dart也没有“线程”。它有可以并行运行的隔离区,但只能通过消息传递进行通信,并且没有像互斥锁这样的同步原语。
在Dart中编写异步代码时,Future.then()语法(尤其是多层嵌套)会变得乏味。幸运的是,async/await功能正在实现,这意味着您可以编写异步代码但读取类似于使用阻塞io编写的代码。例如:
main() async {
var conn = await connect('postgresql://foo');
try {
var sql = "select 'foo'";
var result = await conn.query(sql).toList();
return result[0];
} on Exception catch (ex) {
print('Query error: $ex');
} finally {
conn.close();
}
}
截至11月14日,要使用异步等待,您需要使用--enable_async标志运行dart,并为崩溃和缺少堆栈跟踪信息做好准备 - 此功能正在积极开发中,尚未稳定。另一个更稳定的选择是使用async_await包来翻译您的异步/等待代码以使用期货。
如果您对postgresql驱动程序(我是作者)有任何具体问题,请随时在github中针对它打开一个问题,或者给我发电子邮件。我的电子邮件地址位于postgresql发布页面上。