我正在嘗試將dart與sqlite結合使用,此項目爲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.");
有了這樣的代碼,我不能用飛鏢未來的支持,代碼將在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';
的本地函數映射到一些C++函數在這裏:https://github.com/sam-mccall/dart-sqlite/blob/master/src/dart_sqlite.cc
是否有可能改變異步?如果可能的話,我該怎麼辦?
如果不能,那我不得不重寫它,我必須重寫所有的:
- 鏢文件
- 的C++封裝文件
- 實際的sqlite的驅動程序
更新:
感謝@ GregLowe的評論,Dart的Completer
可以將回調風格轉換爲未來風格,這可以讓我使用Dart的doSomething().then(...)
而不是傳遞迴調函數。
但是看完飛鏢sqlite的根源後,我意識到,在飛鏢的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)。 – mezoni
我修改了它可以正確運行的代碼,但我不喜歡代碼風格。所以我必須重寫代碼,如果我想要異步風格?我必須重寫驅動程序部分(c/C++)以支持異步嗎? – Freewind
你應該可以編寫一個包裝器而不需要觸摸C++。看看如何使用dart中的Completer類:異步。基本上你需要創建一個Completer,立即返回Completer.future,然後從現有的回調中調用Completer.complete(row)。 –