我想知道如何定义数据类型以及如何使用getObject()返回对象(记录)。目前,我能够在获得它的函数之外使用结果(记录)的唯一方法是使用结果调用另一个函数。这样,不需要指定数据类型。但是,如果我想返回值,我需要定义数据类型,我找不到它是什么。我试过“动态”,但似乎没有用。例如“:
fDbSelectOneClient(String sKey, Function fSuccess, String sErmes) {
try {
idb.Transaction oDbTxn = ogDb1.transaction(sgTblClient, 'readwrite');
idb.ObjectStore oDbTable = oDbTxn.objectStore(sgTblClient);
idb.Request oDbReqGet = oDbTable.getObject(sKey);
oDbReqGet.onSuccess.listen((val){
if (oDbReqGet.result == null) {
window.alert("Record $sKey was not found - $sErmes");
} else {
///////return oDbReqGet.result; /// THIS IS WHAT i WANT TO DO
fSuccess(oDbReqGet.result); /// THIS IS WHAT i'm HAVING TO DO
}});
oDbReqGet.onError.first.then((e){window.alert(
"Error reading single Client. Key = $sKey. Error = ${e}");});
} catch (oError) {
window.alert("Error attempting to read record for Client $sKey.
Error = ${oError}");
}
}
fAfterAddOrUpdateClient(oDbRec) {
/// this is one of the functions used as "fSuccess above
答案 0 :(得分:1)
正如其他人曾经说过的那样(无法记住谁),一旦你开始使用异步API,一切都需要异步。
典型的" Dart"要做到这一点的模式是使用Future
+ Completer
对(尽管你在上面的问题中所做的事情没有任何本质上的错误 - 它还有更多风格问题......)。
从概念上讲,fDbSelectOneClient
函数创建一个完整对象,该函数返回completer.future
。然后,当异步调用完成时,您调用completer.complete
,传递值。
该函数的用户将调用fDbSelectOneClient(...).then((result) => print(result));
以异步方式使用结果
您的上述代码可以重构如下:
import 'dart:async'; // required for Completer
Future fDbSelectOneClient(String sKey) {
var completer = new Completer();
try {
idb.Transaction oDbTxn = ogDb1.transaction(sgTblClient, 'readwrite');
idb.ObjectStore oDbTable = oDbTxn.objectStore(sgTblClient);
idb.Request oDbReqGet = oDbTable.getObject(sKey);
oDbReqGet.onSuccess.listen((val) => completer.complete(oDbReqGet.result));
oDbReqGet.onError.first.then((err) => completer.completeError(err));
}
catch (oError) {
completer.completeError(oError);
}
return completer.future; // return the future
}
// calling code elsewhere
foo() {
var key = "Mr Blue";
fDbSelectOneClient(key)
.then((result) {
// do something with result (note, may be null)
})
..catchError((err) { // note method chaining ..
// do something with error
};
}
这个未来/完成对仅适用于一次(即,如果onSuccess.listen
被多次调用,那么第二次你会得到一个"未来已经完成"错误。(我和#39; ve根据函数名fDbSelectOneClient
做了一个假设,你只希望选择一条记录。
要多次从单个未来返回值,您可能必须使用未来的新流功能 - 有关详细信息,请参阅此处:http://news.dartlang.org/2012/11/introducing-new-streams-api.html
另请注意,Futures和Completers支持泛型,因此您可以强烈键入返回类型,如下所示:
// strongly typed future
Future<SomeReturnType> fDbSelectOneClient(String sKey) {
var completer = new Completer<SomeReturnType>();
completer.complete(new SomeReturnType());
}
foo() {
// strongly typed result
fDbSelectOneClient("Mr Blue").then((SomeReturnType result) => print(result));
}