Googled 大量不同的来源,试图连续2天弄清楚,但到目前为止没有任何进展。我很拼命,正在寻找其他人的主意!
我正在尝试在 reduce 函数中应用我编写的异步函数(根据情况可用于promise和回调),因为我正在寻找解析后每个连接对象的值降低了,但是在这一壮举方面我还没有成功。
我想在大量文章 中的每个对象(文章)中应用的功能看起来像 此示例:
renderEngine(
{'author': article.author, 'location': article.location},
'template.xml',
(err, parsedContent) => {
if (err)
callback(err, null)
else
callback(null, parsedContent)
})
如何通过 reduce 使用这样的功能?
答案 0 :(得分:0)
将reduce
与Promises结合使用的一般想法是,每次迭代都要使await
达到累加器的分辨率,其中累加器是Promise
,一旦上一次迭代完成,它就会解析。这是一个实时片段:
const requests = [1, 1, 1];
const resolveAfterSeconds = function(sec) {
return new Promise(res => setTimeout(res, sec * 1000))
}
const doBatch = async function() {
const results = await requests.reduce(async (listP, seconds) => {
/*
the reducer function isn't actually running sequentially itself;
the functions all *start* synchronously immediately,
but each awaits the resolve of the previous iteration before proceeding
*/
const list = await listP;
await resolveAfterSeconds(seconds);
console.log(`returning ${JSON.stringify(listP)}`);
// since this is in an async function, this gets automatically converted to a promise:
return list.concat([seconds]);
}, []);
console.log(`done, results ${JSON.stringify(results)}`);
}
doBatch();
对于您的代码,首先将renderEngine
调用转换为一个返回Promise
的函数,然后在每次迭代中调用该函数非常简单:
const getRender = renderArg => new Promise((resolve, reject) => {
renderEngine(renderArg, (err, parsedContent) => {
if (err) return reject(err);
resolve(parsedContent);
});
const parseArticles = articles => articles.reduce(async (articlesSoFarP, { author, location }) => {
const articlesSoFar = await articlesSoFarP;
const renderedArticle = await getRender({ author, location });
return [...articlesSoFar, renderedArticle];
}, []);
但是,如果您使用for
循环代替,则阅读代码可能会更加清晰:
const parseArticles = async (articles) => {
const parsedArticles = [];
for (const { author, location } of articles) {
const renderedArticle = await getRender({ author, location });
parsedArticles.push(renderedArticle);
}
return parsedArticles;
};