javascript:Async / await in .replace

时间:2015-11-10 13:23:34

标签: javascript async-await es6-promise ecmascript-7

我正在使用async / await函数,方法如下

async function(){
  let output = await string.replace(regex, async (match)=>{
    let data = await someFunction(match)
    console.log(data); //gives correct data
    return data
  })
  return output;
}

但返回的数据是一个promise对象。只是混淆了应该在回调函数中实现它的方式。

4 个答案:

答案 0 :(得分:6)

native replace method不处理异步回调,你不能将它与返回promise的替换器一起使用。

然而,我们可以编写自己的foreach函数来处理承诺:

if($data['type'] != 'Cartthrob_discount_percentage_off_product' AND $data['type'] != 'Cartthrob_discount_percentage_off') {
    //erase continue and put your switch inside of the if statement
    switch($data['type']) {
        //do stuff
    }
}

答案 1 :(得分:4)

所以,没有超载的超载承诺。所以只需重新编写代码:

async function(){
  let data = await someFunction();
  let output = string.replace(regex, data)
  return output;
}

当然,如果你需要使用匹配值传递给异步函数,事情就会变得复杂一些:

var sourceString = "sheepfoohelloworldgoocat";
var rx = /.o+/g;

var matches = [];
var mtch;
rx.lastIndex = 0; //play it safe... this regex might have state if it's reused
while((mtch = rx.exec(sourceString)) != null)
{
    //gather all of the matches up-front
    matches.push(mtch);
}
//now apply async function someFunction to each match
var promises = matches.map(m => someFunction(m));
//so we have an array of promises to wait for...
//you might prefer a loop with await in it so that
//you don't hit up your async resource with all
//these values in one big thrash...
var values = await Promise.all(promises);
//split the source string by the regex,
//so we have an array of the parts that weren't matched
var parts = sourceString.split(rx);
//now let's weave all the parts back together...
var outputArray = [];
outputArray.push(parts[0]);
values.forEach((v, i) => {
    outputArray.push(v);
    outputArray.push(parts[i + 1]);
});
//then join them back to a string... voila!
var result = outputArray.join("");

答案 2 :(得分:4)

使用和理解某些异步替换的简单功能:

async function replaceAsync(str, regex, asyncFn) {
    const promises = [];
    str.replace(regex, (match, ...args) => {
        const promise = asyncFn(match, ...args);
        promises.push(promise);
    });
    const data = await Promise.all(promises);
    return str.replace(regex, () => data.shift());
}

它会执行两次替换功能,因此请注意您是否执行了重要的操作。但对于大多数用途来说,它非常方便。

像这样使用:

replaceAsync(myString, /someregex/g, myAsyncFn)
    .then(replacedString => console.log(replacedString))

或者这个:

const replacedString = await replaceAsync(myString, /someregex/g, myAsyncFn);

不要忘记你的myAsyncFn必须退回承诺。

asyncFunction的一个例子:

async function myAsyncFn(match) {
    // match is an url for example.
    const fetchedJson = await fetch(match).then(r => r.json());
    return fetchedJson['date'];
}

function myAsyncFn(match) {
    // match is a file
    return new Promise((resolve, reject) => {
        fs.readFile(match, (err, data) => {
            if (err) return reject(err);
            resolve(data.toString())
        });
    });
}

答案 3 :(得分:0)

replaceAsync函数通过正则表达式遍历字符串中所有子字符串的出现,并允许您使用异步exampleReplaceFunc函数将它们替换为一个(例如,基于匹配组为参数)。

const replaceAsync = async (str, regex, getNewSubstr) => {
  while (str.match(regex)) {
    const result = str.match(regex);
    const { index } = result;
    const [match, group1] = result;
    const newSubstr = await getNewSubstr(match, group1);
    str = `${str.substr(0, index)}${newSubstr}${str.substr(
      index + match.length
    )}`;
  }
  return str;
};


const exampleReplaceFunc = async (match, group) => {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log(`'${match}' has been changed to 'new${group}'`);
      resolve(`new${group}`);
    }, 1500);
  });
};

const app = async () => {
  const str = "aaaaold1 aaold2aa aold3aa old4 aold5aa";
  console.log('original string:', str) 
  const newStr = await replaceAsync(str, /old([\d])/, exampleReplaceFunc);
  console.log('new string:', newStr);
};

app();