Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/463.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javascript:Async/await in.replace_Javascript_Async Await_Es6 Promise_Ecmascript 2016 - Fatal编程技术网

javascript:Async/await in.replace

javascript:Async/await in.replace,javascript,async-await,es6-promise,ecmascript-2016,Javascript,Async Await,Es6 Promise,Ecmascript 2016,我使用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对象。只是对它

我使用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对象。只是对它在回调函数中的实现方式感到困惑。

因此,没有需要承诺的替换重载。因此,只需重申您的代码:

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("");
不处理异步回调,您不能将其与返回承诺的替换程序一起使用

但是,我们可以编写自己的
replace
函数来处理承诺:

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

function replaceAsync(str, re, callback) {
    // http://es5.github.io/#x15.5.4.11
    str = String(str);
    var parts = [],
        i = 0;
    if (Object.prototype.toString.call(re) == "[object RegExp]") {
        if (re.global)
            re.lastIndex = i;
        var m;
        while (m = re.exec(str)) {
            var args = m.concat([m.index, m.input]);
            parts.push(str.slice(i, m.index), callback.apply(null, args));
            i = re.lastIndex;
            if (!re.global)
                break; // for non-global regexes only take the first match
            if (m[0].length == 0)
                re.lastIndex++;
        }
    } else {
        re = String(re);
        i = str.indexOf(re);
        parts.push(str.slice(0, i), callback.apply(null, [re, i, str]));
        i += re.length;
    }
    parts.push(str.slice(i));
    return Promise.all(parts).then(function(strings) {
        return strings.join("");
    });
}

对于某些异步替换,这是一个易于使用和理解的函数:

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
必须返回一个承诺

异步函数的一个示例:

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())
        });
    });
}

async
函数的返回值始终是一个Promise对象,该对象使用返回的
输出进行解析(或使用抛出的错误进行拒绝)。您是否想知道为什么
output
是一个Promise?我不清楚你的问题是什么。请注意,如果
string.replace
是字面上的
string.prototype.replace
,那么这将不起作用
.replace
希望回调函数是正常函数,而不是异步函数。我已更新了问题。我需要将匹配的元素传递给函数,这样做是不可能的。@ritz078我想你可能错过了这个。也许我的编辑更有用?这只在使用replace迭代匹配时有效。这对替换不起作用,但它确实起作用。它迭代,替换。我真的很喜欢这个解决方案,很好很简单!