Node.js 多个请求同时返回一个结果
Node.js multiple requests at same time and one result returning
多个用户可以同时调用请求,所以我想做的是,如果一个用户调用请求并且正在开始计算结果,那么当另一个用户调用相同的请求时结果计算没有开始,但是等待对于第一个用户要求的结果。换句话说,只有当另一个用户不是 'locked' 时才应该开始计算结果,如果是 - 然后等待结果。
已编辑
代码:
结果:
像这样?
/** @type {[express.Request, express.Response][]} */
let requestQueue = [];
/**
* @param {express.Request} req
* @param {express.Response} res
*/
async function processRequest( req, res ) {
var result = await GetResults();
res.end(result);
if (requestQueue.length !== 0) processRequest.apply(requestQueue.shift());
}
app.get("/getresults", (req, res) => {
if (requestQueue.length !== 0) return requestQueue.push([req, res]);
processRequest(req, res);
});
编辑: 如果他们都收到相同的结果,则此代码:
/** @type {Promise} */
let requestPromise = null;
app.get("/getresults", (req, res) => {
if (requestPromise === null) requestPromise = GetResults().finally(() => requestPromise = null); // returns a promise
res.send(await requestPromise);
});
为了保证并发请求的结果不会被多次计算,你需要实现某种锁定机制(如你所料)。
这是您的代码的一个非常基本的示例,如果互斥量当前已锁定,它只是将请求推送到队列。如果不是,则计算结果,并且对于所有待处理的请求,将发送具有计算值的响应:
const express = require('express');
const app = express();
class Mutex {
constructor() {
this.queue = [];
this.locked = false;
}
lock() {
return new Promise((resolve, reject) => {
if (this.locked) {
this.queue.push([resolve, reject]);
} else {
this.locked = true;
resolve();
}
});
}
release(value) {
if (this.queue.length > 0) {
const [resolve, reject] = this.queue.shift();
resolve(value);
} else {
this.locked = false;
}
}
}
const getResultsMutex = new Mutex();
function getResults() {
return new Promise((resolve => {
setTimeout(() => resolve(Math.random()), 5000);
}))
}
function sendResponse(result, req, res) {
res.send("The result is " + result);
}
app.get('/getresults', async (req, res) => {
let result = await getResultsMutex.lock();
if (!result) {
result = await getResults();
}
sendResponse(result, req, res);
getResultsMutex.release(result);
});
app.listen(4000, function () {
console.log("Server is running at port 4000");
});
多个用户可以同时调用请求,所以我想做的是,如果一个用户调用请求并且正在开始计算结果,那么当另一个用户调用相同的请求时结果计算没有开始,但是等待对于第一个用户要求的结果。换句话说,只有当另一个用户不是 'locked' 时才应该开始计算结果,如果是 - 然后等待结果。
已编辑
代码:
结果:
像这样?
/** @type {[express.Request, express.Response][]} */
let requestQueue = [];
/**
* @param {express.Request} req
* @param {express.Response} res
*/
async function processRequest( req, res ) {
var result = await GetResults();
res.end(result);
if (requestQueue.length !== 0) processRequest.apply(requestQueue.shift());
}
app.get("/getresults", (req, res) => {
if (requestQueue.length !== 0) return requestQueue.push([req, res]);
processRequest(req, res);
});
编辑: 如果他们都收到相同的结果,则此代码:
/** @type {Promise} */
let requestPromise = null;
app.get("/getresults", (req, res) => {
if (requestPromise === null) requestPromise = GetResults().finally(() => requestPromise = null); // returns a promise
res.send(await requestPromise);
});
为了保证并发请求的结果不会被多次计算,你需要实现某种锁定机制(如你所料)。
这是您的代码的一个非常基本的示例,如果互斥量当前已锁定,它只是将请求推送到队列。如果不是,则计算结果,并且对于所有待处理的请求,将发送具有计算值的响应:
const express = require('express');
const app = express();
class Mutex {
constructor() {
this.queue = [];
this.locked = false;
}
lock() {
return new Promise((resolve, reject) => {
if (this.locked) {
this.queue.push([resolve, reject]);
} else {
this.locked = true;
resolve();
}
});
}
release(value) {
if (this.queue.length > 0) {
const [resolve, reject] = this.queue.shift();
resolve(value);
} else {
this.locked = false;
}
}
}
const getResultsMutex = new Mutex();
function getResults() {
return new Promise((resolve => {
setTimeout(() => resolve(Math.random()), 5000);
}))
}
function sendResponse(result, req, res) {
res.send("The result is " + result);
}
app.get('/getresults', async (req, res) => {
let result = await getResultsMutex.lock();
if (!result) {
result = await getResults();
}
sendResponse(result, req, res);
getResultsMutex.release(result);
});
app.listen(4000, function () {
console.log("Server is running at port 4000");
});