【问题标题】:JavaScript Str.Replace with PromisesJavaScript Str.Replace 与 Promises
【发布时间】:2018-01-26 19:42:27
【问题描述】:

我需要在 1 个大字符串变量中进行大约 100 次子字符串替换。

规则是:我需要它是顺序的,以便在第一个替换完成之前无法执行第二个替换。每个后续的替换调用都必须等待,直到第一个调用完成。上一次替换的结果字符串必须使用相同的变量解析到下一次替换调用。

以下在我的情况下不起作用,因为在异步环境中,LINE2 将在 LINE1 之前完成:

LINE1: HTML = HTML.Replace("Roger", SomeLargeFunction());
LINE2: HTML = HTML.Replace("Peter", "John");

我知道这可以通过使用 Promises() 来解决,但我根本无法完成这项工作。你能告诉我我做错了什么吗?

下面是一个示例,只是为了便于理解,但即使是这个简单的代码也不起作用......没有错误,函数只是卡在某个地方。

var MyName = "JOHN LENXYZ";
MyName.replace("X", "N")
      .then(MyName => return MyName.replace("Y","O"))
      .then(MyName => return MyName.replace("Z","N"))
      .then(MyName => console.log ("Right Name: " + MyName))

编辑:我对我的问题不是很清楚,所以请允许我详细说明一下:

HTML 是一个包含大型 HTML 文件的变量,基本上是带有一些子字符串的表格,例如:[FNAME]、[LNAME]、[DOB]、[INCOME] 等。实际上有 100 个这样的子字符串我必须使用自定义表单中的信息来一一替换

在某些情况下,这些子字符串可以替换为直接取自输入字段 ($w("#FirstName").value) 的值,但在其他情况下,可以使用来自自定义函数 () 的值。

看看这个真实案例,这是我的第一个逻辑实现:

LINE 001: HTML = HTML.replace("[DOB]", DateToString($w("#DOBPicker").value));
LINE 002: HTML = HTML.replace("[CALC]", Calculations());
.
.
// THIS REPLACEMENT GETS REPEATED 100 TIMES
.
.
LINE 099: HTML = HTML.replace("[FIRST]", $w("#FirstName").value)
LINE 100: HTML = HTML.replace("[LAST]", $w("#LastName").value);

如您所见,每次替换字符串 HTML 时,都会在下一行中一次又一次地使用它,直到变量 HTML 中的所有子字符串“[xxxxx]”都被完全替换。

现在,这是有趣的部分:由于第 001 行和第 002 行需要比第 099 行和第 100 行更多的时间来处理,令人难以置信的是,第 099 行和第 100 行首先得到结果!!!是的,“REPLACE”在 001 和 002 行之前的 099 和 100 行完全执行。这就是异步执行。

问题是:因为第 002 行中的替换是最后完成的(因为函数 Calculations() 需要更长的时间才能完成),所以从第 003 行到第 100 行的所有替换(已经完成)获取用 HTML 变量在 LINE 002 中的值覆盖。这就像一个回滚效果。

如您所见,这就是我需要在执行下一个替换之前完全完成每个替换的原因。完美的解决方案是使用 Chained Promises,但我就是不知道该怎么做。

我正在使用 JavaScript。 任何帮助将不胜感激,

谢谢。

【问题讨论】:

  • 什么是HTMLPromise?同样在您的第二个示例中,MyName 是一个字符串,而字符串没有 .then 方法。请澄​​清您的问题。
  • 是什么让您的环境异步? JavaScript 通常总是同步执行。您的环境是什么
  • 你可能会说我是一个梦想家,但我不是唯一一个。这个问题可以改进吗?
  • 那么,SomeLargeFunction 返回一个承诺?然后在进行替换之前只需await 即可。还是仅在字符串中实际找到搜索字符串时才调用SomeLargeFunction
  • 您可以将this 作为灵感,尽管它确实同时运行。

标签: javascript string replace callback promise


【解决方案1】:

感谢大家的反馈,非常感谢。 我终于通过这种方式解决了我的问题:

function resolveAfter2Seconds() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('resolved');
    }, 2000);
  });
}

async function asyncCall() {
  console.log('calling');
  var result = await resolveAfter2Seconds();
  console.log(result);
  // expected output: "resolved"
}

asyncCall();

【讨论】:

    猜你喜欢
    • 2016-01-31
    • 1970-01-01
    • 1970-01-01
    • 2022-11-17
    • 2020-08-19
    • 2018-09-13
    • 2014-04-17
    • 1970-01-01
    相关资源
    最近更新 更多