【发布时间】:2014-02-07 15:11:16
【问题描述】:
我正在尝试将 Dart 与 sqlite 一起使用,这个项目是 dart-sqlite。
但是我发现了一个问题:它提供的API是同步风格的。代码将如下所示:
// Iterating over a result set
var count = c.execute("SELECT * FROM posts LIMIT 10", callback: (row) {
print("${row.title}: ${row.body}");
});
print("Showing ${count} posts.");
这样的代码,我无法使用 Dart 未来的支持,代码会阻塞在 sql 操作。
我想知道如何将代码更改为异步样式?你可以在这里看到它定义了一些native 函数:https://github.com/sam-mccall/dart-sqlite/blob/master/lib/sqlite.dart#L238
_prepare(db, query, statementObject) native 'PrepareStatement';
_reset(statement) native 'Reset';
_bind(statement, params) native 'Bind';
_column_info(statement) native 'ColumnInfo';
_step(statement) native 'Step';
_closeStatement(statement) native 'CloseStatement';
_new(path) native 'New';
_close(handle) native 'Close';
_version() native 'Version';
native 函数在这里映射到一些 c++ 函数:https://github.com/sam-mccall/dart-sqlite/blob/master/src/dart_sqlite.cc
是否可以改为异步?如果可以,我该怎么办?
如果不可能,那我必须重写它,我是否必须全部重写:
- 飞镖文件
- c++ 包装文件
- 实际的 sqlite 驱动程序
更新:
感谢@GregLowe 的评论,Dart 的Completer 可以将回调样式转换为未来的样式,这可以让我使用Dart 的doSomething().then(...) 而不是传递回调函数。
但是在阅读了 dart-sqlite 的源码后,我意识到,在 dart-sqlite 的实现中,callback 不是基于事件的:
int execute([params = const [], bool callback(Row)]) {
_checkOpen();
_reset(_statement);
if (params.length > 0) _bind(_statement, params);
var result;
int count = 0;
var info = null;
while ((result = _step(_statement)) is! int) {
count++;
if (info == null) info = new _ResultInfo(_column_info(_statement));
if (callback != null && callback(new Row._internal(count - 1, info, result)) == true) {
result = count;
break;
}
}
// If update affected no rows, count == result == 0
return (count == 0) ? result : count;
}
即使我使用Completer,也不会提高性能。我想我可能必须先重写 c++ 代码以使其基于事件。
【问题讨论】:
-
此代码已过时,因为编写于 2 年前。所以,你的问题仍然不实际。除非你不想自己重写它(dart-sqlite)。
-
我修改了可以正常运行的代码,但是我不喜欢代码风格。所以如果我想要异步风格,我必须重写代码吗?是否必须重写驱动部分(c/c++)才能支持异步?
-
您应该能够在不接触 C++ 的情况下编写包装器。看看如何在 dart:async 中使用 Completer 类。基本上你需要创建一个 Completer,立即返回 Completer.future,然后从现有回调中调用 Completer.complete(row)。
-
回复:更新。你看过下面链接的文章,特别是关于异步扩展的那篇文章吗?即,如果 C++ API 是同步的,您可以在单独的线程中运行它,并使用消息传递与其通信。这可能是一种方法。 dartlang.org/articles/native-extensions-for-standalone-dart-vm
-
@GregLowe,非常感谢!这正是我正在寻找的,它回答了我所有的问题。可以把它作为答案,我会接受它
标签: sqlite asynchronous dart synchronous