【问题标题】:String.replaceAllMapped with asynchronous result带有异步结果的 String.replaceAllMapped
【发布时间】:2015-12-17 19:35:20
【问题描述】:

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

如何让 async/await 在这种情况下工作? 我还为 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&lt;String&gt; 替换哪个部分?您在调用 replaceAllMapped? 时读取的文件内容
  • 这种函数没有内置版本,你必须编写一个期望回调函数是异步的,如下面的 Tonio。

标签: dart async-await


【解决方案1】:

试试这个:

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

【讨论】:

  • 我建议使用StringBuffer 来收集这些部分,而不是使用具有潜在二次执行时间的重复连接。或者只是收集列表中的部分并在最后使用List.join
  • True... 编辑了答案以使用 StringBuffer 而不是字符串连接/插值。
  • 您的解决方案中有一个小错字。 ..write(prefix) 之后不应有分号。感谢您提供有效的解决方案。从真正的多线程开发到事件循环的过渡非常困难。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-01
  • 2017-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多