为了账号安全,请及时绑定邮箱和手机立即绑定

在 JavaScript 中为每个用户同步 API 中的关键部分

在 JavaScript 中为每个用户同步 API 中的关键部分

扬帆大鱼 2022-05-26 14:08:50
我想交换用户的个人资料图片。为此,我必须检查数据库以查看是否已保存图片,如果已保存,则应将其删除。然后应该保存新的并输入数据库。这是一个简化的(伪)代码: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?


查看完整回答
反对 回复 2022-05-26
  • 1 回答
  • 0 关注
  • 176 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号