工厂等待Future构造对象

时间:2015-07-01 21:33:49

标签: dart firebase

如何让Factory内的Future同步?我在这里向客户端返回null。

  factory Project.retrieve(String hash, CompetencesService service) {
    Project project;
    service.dbRef.child("project").once("value").then((snapshot) {
      Map val = snapshot.val();
      project = toObservable(new Project.fromJson(val));

      if(project != null) {
        project.listen(service);
        print("listening1");
      } else {
        project = toObservable(new Project.newHash(hash));
        service.dbRef.child("project").update(project.toJson()).then((error) {
          if(error) {
            //
          } else {
            project.listen(service);
            print("listening2");
          }
        });
      }
    });
    return project;
  }

有人asked为此,但我正在寻找解决方法的示例。

2 个答案:

答案 0 :(得分:1)

目前无法创建异步构造函数或工厂,也无法同步等待Future

后者是一个明显的原因:如果你将停止并同步等待当前孤立本身的某些东西(不是像文件i / o这样的外部事件),它将永远不会发生,因为Isolate在单线程在等待状态下停止。

所以,这里唯一的方法是让静态方法返回Future Project实例,就像你提供的链接中提到的那样:

static Future<Project> retrieve() async {
  var snapshot = await service.dbRef.child("project").once("value");
  Project project = toObservable(new Project.fromJson(snapshot.val()));

  ...

  return project; // Note you're actually returning a Future here
}

答案 1 :(得分:0)

我尝试实现Future界面,然后是工厂&amp;构造函数可以返回Future并且能够await

@proxy
class AsyncFact implements Future {
  factory AsyncFact() {
    return new AsyncFact._internal(new Future.delayed(
        const Duration(seconds: 1), () => '[Expensive Instance]'));
  }

  AsyncFact._internal(o) : _mirror = reflect(o);

  final InstanceMirror _mirror;
  @override
  noSuchMethod(Invocation invocation) => _mirror.delegate(invocation);
}

@proxy
class AsyncConst implements Future {
  AsyncConst() : _mirror = reflect(new Future.delayed(
          const Duration(seconds: 1), () => '[Expensive Instance]'));

  final InstanceMirror _mirror;
  @override
  noSuchMethod(Invocation invocation) => _mirror.delegate(invocation);
}

main() async {
  print(await new AsyncFact()); // [Expensive Instance]
  print(await new AsyncConst()); // [Expensive Instance]
}