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

我想交换用户的个人资料图片。为此,我必须检查数据库以查看是否已保存图片,如果已保存,则应将其删除。然后应该保存新的并输入数据库。


这是一个简化的(伪)代码:


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

表示

同步

临界区


扬帆大鱼
浏览 177回答 1
1回答

慕森卡

你可以使用一个库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?
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript