我正在一个需要模板的项目中。主模板具有一个导入属性,用于指定数据源。然后使用String.replaceAllMapped读取数据并将其插入到字符串中。以下代码可与File api一起正常使用,因为它具有readAsStringSync方法来同步读取文件。我现在想从任何返回Future的流中读取。

在这种情况下,如何使异步/等待工作?
我还寻找了replaceAllMapped的异步兼容替代品,但是我没有找到不需要多次使用正则表达式的解决方案。

这是我的代码的非常简化的示例:

String loadImports(String content){
  RegExp exp = new RegExp("import=[\"\']([^\"\']*)[\"\']>\\s*<\/");

  return content.replaceAllMapped(exp, (match) {
    String filePath = match.group(1);

    File file = new File(filePath);
    String fileContent = file.readAsStringSync();

    return ">$fileContent</";
  });
}

用法示例:
print(loadImports("<div import='myfragment.txt'></div>"))

最佳答案

试试这个:

Future<String> replaceAllMappedAsync(String string, Pattern exp, Future<String> replace(Match match)) async {
  StringBuffer replaced = new StringBuffer();
  int currentIndex = 0;
  for(Match match in exp.allMatches(string)) {
    String prefix = match.input.substring(currentIndex, match.start);
    currentIndex = match.end;
    replaced
       ..write(prefix)
       ..write(await replace(match));
  }
  replaced.write(string.substring(currentIndex));
  return replaced.toString();
}

要使用上面的示例:
Future<String> loadImports(String content) async {
    RegExp exp = new RegExp("import=[\"\']([^\"\']*)[\"\']>\\s*<\/");

    return replaceAllMappedAsync(content, exp, (match) async {
        String filePath = match.group(1);

        File file = new File(filePath);
        String fileContent = await file.readAsString();
        return ">$fileContent</";
    });
}

像这样使用:
loadImports("<div import='myfragment.txt'></div>").then(print);

或者,如果在async函数中使用:
print(await loadImports("<div import='myfragment.txt'></div>"));

09-11 05:43