我正在一个需要模板的项目中。主模板具有一个导入属性,用于指定数据源。然后使用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>"));