indexed_db getObject() - 如何返回结果 [英] indexed_db getObject() - how to return result
问题描述
我想知道如何定义数据类型,以及如何使用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 is found - $ sErmes);
} else {
/////// return oDbReqGet.result; ///这是我想要做的事
fSuccess(oDbReqGet.result); // /这是我要做的
}});
oDbReqGet.onError.first.then((e){window.alert(
读取单个客户端错误。 $ sKey.Error = $ {e});});
} catch(oError){
window.alert(尝试读取客户端$ sKey的记录时出错
Error = $ {oError});
}
}
fAfterAddOrUpdateClient(oDbRec){
///这是用作fSuccess的函数之一
正如别人曾经说过(不记得谁),一旦你开始使用一个异步API,一切都需要异步。
典型的Dart模式是使用 Future
+ Completer
pair(虽然你在上面的问题中没有什么错误 - 这更像是一个风格问题)。
概念上, fDbSelectOneClient
函数创建一个完成对象,函数返回 completer.future
。然后,当异步调用完成时,您调用 completer.complete
,传递值。
该函数将调用 fDbSelectOneClient(...)。then((result)=> print(result));
p>
您的代码可以重构如下:
import'dart:async'; //完成者需要
未来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
}
//调用其他地方的代码
foo(){
var key =Mr Blue;
fDbSelectOneClient(key)
.then((result){
//对结果做一些事情(注意,可能为null)
})
..catchError((err){// note method chaining ..
//执行错误
};
}
这个future / completer对只适用于一次镜头(即,如果 onSuccess.listen
被多次调用,那么第二次你会得到一个未来已经完成的错误(我做了一个假设基于函数名 fDbSelectOneClient
,你只是期望选择单个记录。
要多次返回单个未来的值,您可能需要使用未来的新流功能 - 详情: http://news.dartlang.org/2012/11 /introducing-new-streams-api.html
请注意,Futures和Completers支持泛型,因此您可以强烈地键入返回类型,如下所示:
//强类型未来
Future< SomeReturnType> fDbSelectOneClient(String sKey){
var completer = new Completer< SomeReturnType>();
completer.complete(new SomeReturnType());
}
foo(){
//强类型化结果
fDbSelectOneClient(Mr Blue)。 ));
}
I would like to know how to define the data type and how to return the object (record) using getObject(). Currently, the only way that I have been able to use the result (record) outside of the function that obtains it is to call another function with the result. That way, the data-type does not need to be specified. However if I want to return the value, I need to define the data-type and I can't find what it is. I tried "dynamic" but that didn't appear to work. For example ":
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
As someone else once said (can't remember who), once you start using an async API, everything needs to be async.
A typical "Dart" pattern to do this would be to use a Future
+ Completer
pair (although there's nothing inherently wrong with what you've done in your question above - it's more a question of style...).
Conceptually, the fDbSelectOneClient
function creates a completer object, and the function returns the completer.future
. Then, when the async call completes, you call completer.complete
, passing the value in.
A user of the function would call fDbSelectOneClient(...).then((result) => print(result));
to make use of the result in an async way
Your code above could be refactored as follows:
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
};
}
This future/completer pair only works for one shot (ie, if the onSuccess.listen
is called multiple times, then the second time you will get a "Future already completed" error. (I've made an assumption on the basis of the function name fDbSelectOneClient
that you are only expecting to select a single record.
To return a value from a single future multiple times, you'll probably have to use the new streams feature of the Future - see here for more details: http://news.dartlang.org/2012/11/introducing-new-streams-api.html
Note also, that Futures and Completers support generics, so you can strongly type the return type as follows:
// 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));
}
这篇关于indexed_db getObject() - 如何返回结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!