我想交换用户的个人资料图片。为此,我必须检查数据库以查看是否已保存图片,如果已保存,则应将其删除。然后应该保存新的并输入数据库。这是一个简化的(伪)代码:async function changePic(user, file) { // remove old pic if (await database.hasPic(user)) { let oldPath = await database.getPicOfUser(user); filesystem.remove(oldPath); } // save new pic let path = "some/new/generated/path.png"; file = await Image.modify(file); await Promise.all([ filesystem.save(path, file), database.saveThatUserHasNewPic(user, path) ]); return "I'm done!";}我遇到了以下问题:如果用户在短时间内两次调用API,则会出现严重错误。数据库查询和其间的函数是异步的,导致当第二个 API 检查要删除的配置文件图片时,没有应用第一个 API 调用的更改。所以我 filesystem.remove需要一个已经不存在的文件和文件系统中未删除的图像的请求。我想通过同步这段代码的关键部分来安全地处理这种情况。我不想仅仅因为服务器还没有完成前一个请求而拒绝请求,我也想为每个用户同步它,这样用户就不会被其他用户的操作所困扰。有没有一种干净的方法可以在 JavaScript 中实现这一点?像你从 Java 中知道的某种监视器会很好。javascript节点.js表示同步临界区
1 回答
慕森卡
TA贡献1806条经验 获得超8个赞
你可以使用一个库p-limit来控制你的并发性。使用地图跟踪每个用户的活动/待处理请求。使用他们的 ID(我假设存在)作为键,使用限制实例作为值:
const pLimit = require('p-limit');
const limits = new Map();
function changePic(user, file) {
async function impl(user, file) {
// your implementation from above
}
const { id } = user // or similar to distinguish them
if (!limits.has(id)) {
limits.set(id, pLimit(1)); // only one active request per user
}
const limit = limits.get(id);
return limit(impl, user, file); // schedule impl for execution
}
// TODO clean up limits to prevent memory leak?
添加回答
举报
0/150
提交
取消
