我有两个异步函数,它们彼此重复很多代码,并且我正在尝试找出一种方法来将这些重复代码分解为由这两个函数调用的备用函数。
我的第一个函数如下所示(实际上还有更多与要聚合的消息相关的代码):
const getAllMessageStats() = async (userId: string) => {
const messageIds = await getUserMessageIds(userId);
const messagesRead = 0;
const reactionsTotal = 0;
const moreStats = [];
for (const messageId of messageIds) {
const message = await getMessage(messageId);
if (message.read) messagesRead++;
reactionsTotal += message.reactions;
const otherStats = [];
for (const otherDataId of message.otherDataIds) {
otherData = await getOtherData(otherDataId)
otherStats.push(doLotsOfOtherCalcs(otherData));
}
moreStats.push(otherStats);
}
return {
messagesRead,
reactionsTotal,
moreStats
}
};
我的第二个函数看起来像这样
const getMessageStats() = async (messageId: string) => {
const message = await getMessage(messageId);
const otherStats = [];
for (const otherDataId of message.otherDataIds) {
otherData = await getOtherData(otherDataId)
otherStats.push(doLotsOfOtherCalcs(otherData));
}
const miscData = await getMiscData(messageId);
return {
read: message.read,
reactions: message.reactions,
otherStats,
miscData
}
我尝试了以下方法:
const sharedFunction() = async (messageId: string) => {
const message = await getMessage(messageId);
const otherStats = [];
for (const otherDataId of message.otherDataIds) {
otherData = await getOtherData(otherDataId)
otherStats.push(doLotsOfOtherCalcs(otherData));
}
return {
read: message.read,
reactions: message.reactions,
otherStats
}
};
const getMessageStats() = async (messageId: string) => {
const { read, reactions, otherStats } = await sharedFunction(messageId);
const miscData = await getMiscData(messageId);
return {
read,
reactions,
otherStats,
miscData
}
};
const getAllMessageStats() = async (userId: string) => {
const messageIds = await getUserMessageIds(userId);
const messagesRead = 0;
const reactionsTotal = 0;
const moreStats = [];
for (const messageId of messageIds) {
const { read, reactions, otherStats } = await sharedFunction(messageId);
if (read) messagesRead++;
reactionsTotal += reactions;
moreStats.push(otherStats);
}
return {
messagesRead,
reactionsTotal,
moreStats
}
};
但是,我的函数
getAllMessageStats
现在执行时间增加了 3 倍以上,特别是当我有数千条消息发送给用户时。在看到这篇关于异步/等待开销的文章之后,我现在明白了原因。但我的问题是:我现在是否仍坚持原来的重复代码?当然有更优雅的解决方案,对吗?
Promise.all
并行执行异步函数,然后循环其结果:
Promise.all(messageIds.map(messageId => sharedFunction(messageId)))
.then(function(sharedFunctionResults) {
for (const { read, reactions, otherStats } of sharedFunctionResults) {
...
}
});