当我发现我必须从内部函数中返回外部函数值时,我在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;}
}
此函数是我用于保存和加载到索引数据库的类的方法。
当删除操作成功或失败时,我希望此函数返回true
或false
或包含该函数的Future对象。但是,瓶颈是os.delete(_key);
语句:它返回一个未来,但删除操作的实际成功或失败由tx.onComplete
和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的方法来避免这个问题?
答案 0 :(得分:5)
您可以使用Completer
。
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