我应该在这一系列Future函数中将completer.complete()放在哪里?

时间:2015-02-23 15:52:54

标签: dart future dart-async

我的功能必须创建一个目录,并将整个文件夹层次结构从另一个目录复制到这个新目录。所有的操作都是异步完成的,但是我希望这个函数返回一个Future,当我调用.then(result)时,它将完成所有的异步工作。

但我不知道我应该把completer.complete()放到哪里来实现这一目标。

    
Future<Directory> createCopyDirectory(Directory directoryToCreate){
  Completer<Directory> completer = new Completer<Directory>();
  completer.complete(
      directoryToCreate.create().then((directory){
        Directory contentToCopy = new Directory(globalPathOfDirectoryToCopy);
        List<Future> creatingContent = new List<Future>();
        contentToCopy.list(recursive:true, followLinks:false).forEach((f){
          if (f is File){
            File fileToCreate = new File(f.path.replaceFirst('pages', userID));
            creatingContent.add(fileToCreate.create(recursive:true).then((_){
              f.readAsString().then((fileContent){
                fileToCreate.writeAsString(fileContent);
              });
            }));
          }
        });
        return Future.wait(creatingContent).then((_){ return directoryToCreate;});
    })
  );
  return completer.future;
}

我确切地说我的功能像预期的那样工作但是如果我尝试直接访问我应该在这个函数中创建的内容,就像在then()调用中一样,Dart给我带来了一些我没有创建过的内容。因此,completer.complete()肯定位置不佳,并在创建内容之前调用then()

我尝试使用结尾completer.complete()上的Future.wait(creatingContent)或将return directoryToCreate替换为completer.complete(directoryToCreate),但结果是相同的。

我对在这种情况下构建适当的基于Future的功能的方式感到有点困惑。

1 个答案:

答案 0 :(得分:1)

你在这里不需要Completer

Future<Directory> createCopyDirectory(Directory directoryToCreate) {
  return directoryToCreate.create().then((directory) {
    String userID = split(userDirectory.path).last;
    Directory contentToCopy = new Directory(globalPathOfDirectoryToCopy);
    List<Future> creatingContent = new List<Future>();
    return contentToCopy
        .list(recursive: true, followLinks: false)
        .forEach((File f) {
      if (f is File) {
        File fileToCreate = new File(f.path.replaceFirst('pages', userID));
        creatingContent.add(fileToCreate.create(recursive: true).then((_) {
          return f.readAsString().then((fileContent) {
            return fileToCreate.writeAsString(fileContent);
          });
        }));
      }
    }).then((_) {
      return Future.wait(creatingContent).then((_) {
        return directoryToCreate;
      });
    });
  });
}

只是为了演示如何使用Completer

Future<Directory> createCopyDirectory(Directory directoryToCreate) {
  Completer<Directory> completer = new Completer<Directory>();
  directoryToCreate.create().then((directory) {
    String userID = split(userDirectory.path).last;
    Directory contentToCopy = new Directory(globalPathOfDirectoryToCopy);
    List<Future> creatingContent = new List<Future>();
    contentToCopy.list(recursive: true, followLinks: false).forEach((f) {
      if (f is File) {
        File fileToCreate = new File(f.path.replaceFirst('pages', userID));
        creatingContent.add(fileToCreate.create(recursive: true).then((_) {
          return f.readAsString().then((fileContent) {
            return fileToCreate.writeAsString(fileContent);
          });
        }));
      }
    }).then((_) => Future
        .wait(creatingContent)
        .then((_) => completer.complete(directoryToCreate)));
  });
  return completer.future;
}