indexed_db getObject() - 如何返回结果 [英] indexed_db getObject() - how to return result

查看:120
本文介绍了indexed_db getObject() - 如何返回结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道如何定义数据类型,以及如何使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆