2013-02-04 29 views
0

我想知道如何定義數據類型以及如何使用getObject()返回對象(記錄)。目前,我能夠在獲得它的函數之外使用結果(記錄)的唯一方法就是調用另一個函數的結果。這樣,數據類型不需要指定。但是,如果我想返回值,我需要定義數據類型,我找不到它是什麼。我嘗試「動態」,但似乎沒有工作。例如「:indexed_db 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

至於別人說過(不記得是誰),一旦你開始使用異步API,一切都必須是異步

一個典型。‘達特’的圖案做這將是使用Future + Completer對(雖然沒有什麼本質上的錯誤與你在上面你的問題做了什麼 - 這是更多的風格問題......)。

從概念上講,fDbSelectOneClient函數創建一個完成者對象,並且函數返回completer.future。然後,當異步SOS呼叫完成,你叫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,那麼第二次您將獲得「未來已完成」錯誤。 (我在功能名稱fDbSelectOneClient的基礎上做了一個假設,你只希望選擇一條記錄。

要多次返回單個未來的值,您可能必須使用新的未來的數據流的功能 - 在這裏看到更多的細節:http://news.dartlang.org/2012/11/introducing-new-streams-api.html

還要注意,期貨和完成者支持泛型,所以你可以強類型的返回類型如下:

// 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)); 
} 
+1

感謝克里斯,我會盡快詳細檢查你的答案,這應該有助於我更好地理解事情。一旦我完成了,我會的給它打個勾。 –