我对诺言比较陌生,而且遇到了问题。
我有一个函数,希望能够对给定的文本进行一堆字符串替换,其中一些包含从api调用返回的值。
parseText(text) {
text.replace(/\n|\r\n|\r/g, ' ')
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/<#(C\w+)\|?(\w+)?>/g, (match, id, read) => {
return apiMethod(id).then(resp => resp.name)
})
.then(newText => {
return newText.replace(/(-\w+)>/g, (match, id) => {
apiMethod(id).then(resp => resp.name)
}
});
}
如何使替换与apiMethod
Promise的返回值一起使用?
答案 0 :(得分:2)
一个选择是为每个请求创建一个Promises数组,在数组上调用Promise.all
,然后创建一个由id
索引的对象(正则表达式中的第一组)。然后,再次调用.replace
,并用适当的索引键替换。因为您必须异步替换多次,所以将其放入自己的函数中以使代码变干:
const asyncReplace = async (str, regex) => {
const promises = [];
// does not actually replace anything, just builds the promises:
str.replace(regex, (match, id, read) => {
promises.push(apiMethod(id).then(resp => [id, resp.name]));
});
const results = await Promise.all(promises);
const replacements = results.reduce((a, [id, name]) => {
a[id] = name;
return a;
}, {});
return str.replace(regex, (match, id, read) => replacements[id]);
}
parseText(text) {
const str = text.replace(/\n|\r\n|\r/g, ' ')
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>');
return asyncReplace(str, /<#(C\w+)\|?(\w+)?>/g)
.then((str2) => asyncReplace(str2, /<#(C\w+)\|?(\w+)?>/g))
}
实时摘要:
// encloses the match in underscores
const apiMethod = substr => Promise.resolve('_' + substr + '_');
const asyncReplace = async (str, regex) => {
const promises = [];
// does not actually replace anything, just builds the promises:
str.replace(regex, (match, id, read) => {
promises.push(apiMethod(id).then(resp => [id, resp]));
});
const results = await Promise.all(promises);
const replacements = results.reduce((a, [id, name]) => {
a[id] = name;
return a;
}, {});
return str.replace(regex, (match, id, read) => replacements[id]);
}
function parseText(text) {
// put underscores around every space...
return asyncReplace(text, /( )/g)
// ...twice:
.then((str2) => asyncReplace(str2, /( )/g))
}
parseText('foo bar baz')
.then(res => console.log(res));