我很喜欢Dart中的异步/等待模式.
但是,有几件事是有问题的,特别是有一件事,我根本不知道该如何处理.
问题是,在一个方法中使用异步和多重等待时,我们在该方法中引入了并发性.
Future<int> foo(int value) async {
await foo2();
await foo3();
await foo4();
int ret = foo5(value);
return ret;
}
这是一个非常简单的例子.
请考虑该方法是否管理对类实例而不是方法本身所共有的数据.
因此,我try 了以下解决方案:
bool isWorking = false;
Future<int> foo(int value) async {
if (isWorking) return foo(value);
isWorking = true;
await foo2();
await foo3();
await foo4();
int ret = foo5(value);
isWorking = False;
return ret;
}
据我所知,调用将来的方法会将其立即放入事件循环中,所以我认为该方法的并发调用的执行会延迟到第一个调用结束. 但事实并非如此,程序进入了一个无穷无尽的循环.
有人能给我一个解释和解决这个问题的方法吗?
编辑: 总的来说,我认为像在其他语言中一样,拥有一个同步关键字可能很有趣,意思是如果第二次调用该方法,它将等到第一次调用结束. 类似于:
Future<int> foo(int value) async synchronized {
编辑2:
我真的很兴奋,因为我想我已经解决了这个问题很长一段时间了.感谢阿根廷,特别是亚历山大,他们给了我解决方案.为了便于重用(至少对我来说是这样),我简单地重新构建了解决方案,并在此发布了我创建的类和一个示例,说明如何为那些可能需要它的人使用它(try 风险自负;-). 我使用了Mixin,因为我发现它很实用,但是如果您愿意,您可以单独使用Locker类.
myClass extends Object with LockManager {
Locker locker = LockManager.getLocker();
Future<int> foo(int value) async {
_recall() {
return foo(value);
}
if (locker.locked) {
return await locker.waitLock();
}
locker.setFunction(_recall);
locker.lock();
await foo2();
await foo3();
await foo4();
int ret = foo5(value);
locker.unlock();
return ret;
}
}
课程是:
import 'dart:async';
class LockManager {
static Locker getLocker() => new Locker();
}
class Locker {
Future<Null> _isWorking = null;
Completer<Null> completer;
Function _function;
bool get locked => _isWorking != null;
lock() {
completer = new Completer();
_isWorking = completer.future;
}
unlock() {
completer.complete();
_isWorking = null;
}
waitLock() async {
await _isWorking;
return _function();
}
setFunction(Function fun) {
if (_function == null) _function = fun;
}
}
我以这种方式组织了代码,以便您可以在类中的多个方法中轻松使用它.在这种情况下,每个方法都需要一个Locker实例. 我希望它能有所帮助.