我不知道这个问题是否已经有了解决方案,但我找不到它,或者我不知道要搜索什么。
我有一个返回产品列表的rest api,我想在第一个调用api的人的响应中添加一个优惠券代码,我使用redis来缓存收到代码的用户的信息,该代码在15分钟内过期。
async function addVoucherCode(response, userId) {
try {
const key = "KEY_VOUCHER_CODE";
let cachedData = await redis.get(key);
if (cachedData) {
if (cachedData.userId === userId) response.voucherCode = cachedData.voucherCode;
return;
}
const voucherCode = await createVoucherCode(userId); //call to create voucher code and save to db
if (!voucherCode) return;
await redis.setEx(key, 15 * 60, {userId, voucherCode});
response.voucherCode = cachedData.voucherCode;
} catch (err) {
console.error("[Error] addVoucherCode: ", err);
}
}
我创建了一个函数来模拟一个同时请求,当我检查响应时,所有的请求都有一个优惠券代码,而不仅仅是第一个。
async function getProducts(url, params) {
try {
const customers = [
{ id: 1, token: "Bearer eyJhbGciOi....1" },
{ id: 2, token: "Bearer eyJhbGciOi....2"},
{ id: 3, token: "Bearer eyJhbGciOi....3"},
{ id: 4, token: "Bearer eyJhbGciOi....4"}
];
const data = await Promise.all(customers.map( async customer => {
return await fetch(url + "?" + params.toString(), {
headers: {
Authorization: customer.token
},
}).then(res => res.json());
}));
data.forEach((item, indx) => {
if(item.voucherCode) {
const id = customers[indx].id;
console.log(`Customer ${id} has a voucher!!!!!!!!!!!!!`)
}
})
} catch (err) {
console.error("[Error] getProducts: ", err);
}
}
测试结果
Customer 1 has a voucher!!!!!!!!!!!!!
Customer 2 has a voucher!!!!!!!!!!!!!
Customer 3 has a voucher!!!!!!!!!!!!!
Customer 4 has a voucher!!!!!!!!!!!!!
我试着在addVoucherCode中添加一个200ms的延迟,但是结果是一样的。提前感谢你的帮助。
1条答案
按热度按时间zyfwsgd61#
您在同步循环中调用
addVoucherCode
,因此它将并行运行4次(4个GET
命令将同时发出,它将对所有命令返回null,所有命令都将调用createVoucherCode
)。有两件事可以做来修复它:
1.缓存承诺
createVoucherCode
:注意:如果同时运行多个节点进程,则此操作无法解决问题。
1.将
SET
与NX
(不会覆盖现有值)和GET
(返回现有/旧值)一起使用