2

我正在 dart 中编写一个函数,该函数将从浏览器端的索引数据库中删除一个对象,当我发现我必须从内部函数中返回一个外部函数值时:

Future<bool> delete() {
    Transaction tx = db.transactionStore(storeName, "readwrite");
    ObjectStore os = tx.objectStore(storeName);
    os.delete(_key); // returns blank future, modifies tx

    // This is not correct, but shows the idea:
    if (tx.onComplete) {return true;}
    if (tx.onError) {return false;}
}

此函数是我用来保存和加载到索引数据库的类的方法。当删除操作成功或失败时,我希望此函数返回trueorfalse或包含相同内容的 Future 对象。但是,瓶颈在于os.delete(_key);语句:它返回一个未来,但删除操作的实际成功或失败由tx.onCompleteand提供tx.onError。这两个对象都是流,所以我需要创建匿名函数来处理来自它们的事件:

tx.onComplete.listen((e){
    return_to_outer_function(true);
});
tx.onError.listen((e){
    return_to_outer_function(false);
});
return_to_outer_function(bool) {
    return bool; // doesn't work
}

如您所见,当我创建匿名函数时,return 语句不再完成方法,而是内部函数。我可以让内部函数调用其他函数,但是那些其他函数有自己的 return 语句,它们不会将结果返回给整个方法。

我尝试了设置临时变量并定期检查它们的方法,但这是一个非常不雅的解决方案,我不想使用它,不仅是为了潜在的错误,而且因为它会占用单线程事件循环。

是否可以从内部函数向外部函数返回值?还是有其他更好的方法可以从一组流中事件的存在或不存在中获取值?还是有另一种使用 IndexedDB 的方法可以避免这个问题?

4

1 回答 1

6

您可以Completer为此使用 a 。

Future<bool> delete() {
  Completer completer = new Completer();
  Transaction tx = db.transactionStore(storeName, "readwrite");
  ObjectStore os = tx.objectStore(storeName);

  tx.onError.first((e){
    //return_to_outer_function(false);
    completer.complete(false);
  });
  tx.onComplete.first(bool) {
    //return bool; // doesn't work
    completer.complete(true)
  }
  os.delete(_key); // register listeners and then do delete to be on the save side

  return completer.future;
}

然后你称之为

delete().then((success) => print('succeeded: $success'));

另请参阅https://api.dartlang.org/apidocs/channels/be/dartdoc-viewer/dart:async.Completer

于 2014-07-06T21:26:44.073 回答