【发布时间】:2021-07-04 20:35:14
【问题描述】:
我一直在尝试使用 async-lock npm 模块来锁定 /get 资源执行。
import cors from "cors";
import express from "express";
import AsyncLock from "async-lock";
import _ from "lodash";
const app = express();
const port = process.env.port || 3001;
app.use(cors());
app.use(express.json());
let synchonizationKey: string = "";
let lock = new AsyncLock();
app.get("/pckg", (req, res) => {
let id = _.uniqueId();
console.log("--------------Request ", id, " arrived");
lock.acquire(
synchonizationKey,
function () {
console.log("--------------Request ", id, " lockAquired");
setTimeout(function () {
console.log("--------------Request ", id, " Done");
}, 3000);
},
function (err, ret) {
console.log("--------------Request ", id, " lockReleased");
res.send({ id: id });
},
{}
);
});
app.listen(port, () => console.log("Running on port#" + port));
输出:我从浏览器发出的 4 个获取请求。
--------------Request 1 arrived
--------------Request 1 lockAquired
--------------Request 1 lockReleased
--------------Request 2 arrived
--------------Request 2 lockAquired
--------------Request 2 lockReleased
--------------Request 3 arrived
--------------Request 3 lockAquired
--------------Request 3 lockReleased
--------------Request 4 arrived
--------------Request 4 lockAquired
--------------Request 4 lockReleased
--------------Request 1 Done
--------------Request 2 Done
--------------Request 3 Done
--------------Request 4 Done
我期待得到与question 中回答的类似行的结果
看起来,一旦回调中的所有同步部分执行完毕,锁就会被释放。
有人可以帮我解决这个问题吗?
【问题讨论】:
-
应该有一个函数叫
done,next等...你需要在你的setTimeout代码块中手动调用它,如果有错误,一般需要通过它在那个函数中像:next(error),在这种情况下,async-lock解决了什么类型的问题?你让它变得复杂了,你现在不需要任何回调库......改用标准async/await -
客户端可以调用 /pckg 来运行一系列异步调用。这些异步调用需要在 /pckg get 请求中得到保护。
-
@Nur 在某些情况下您可能需要锁。例如,多个客户端读取和更新同一个文件,其中第二个客户端不得开始读取文件,而另一个客户端尚未完成更新。当然,每个人都可以使用
async/await自己编写这样的锁定,但没有必要让每个人都重新发明轮子。是的,现在可能首选基于承诺的方法——这也得到了库的支持。但是使用基于回调的方法仍然没有错...
标签: node.js asynchronous