2015-12-17 71 views
5

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

如何在此场景中使异步/等待工作? 我也寻找一个异步兼容替换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>")) 
+0

我不知道我理解你想要做什么,那就是,这部分你想用'Future '代替?您在调用'replaceAllMapped'内部读取的文件内容? – Tonio

+0

没有这样的函数的内置版本,你必须编写一个需要回调函数为异步的函数,就像下面的Tonio一样。 – lrn

回答

2

试试这个:

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>")); 
+1

我推荐使用'StringBuffer'来收集部件,而不是使用重复级联,并且可能有二次执行时间。或者只是收集列表中的部分,并在末尾使用'List.join'。 – lrn

+0

True ...编辑了使用'StringBuffer'而不是字符串连接/插值的答案。 – Tonio

+1

您的解决方案中有一个小错字。在..write(前缀)之后不应该有分号。感谢您提供可行的解决方案。从真正的多线程开发到事件循环的过渡是非常困难的。 – Zig158