indexed_db getObject() - 如何返回结果

时间:2013-02-04 05:46:18

标签: dart

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

1 个答案:

答案 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));
}