[好,您不希望在startAsyncFlow()
请求处理程序中发送响应之前先完成/start
。因此,如果客户端立即发出另一个请求,则很可能是startAsyncFlow()
尚未完成,因此会话数据尚未保存。等待足够长的时间,可能会(如果没有被其他请求覆盖)。
我遇到了一些很奇怪的情况,实际上无法理解正在发生的事情。感谢您对以下原因的任何解释。
我有带有Express和Express-Session的Node.js服务器
我需要有一个端点,该端点将异步启动某些流程,这意味着客户端发送命令开始耗时,并且客户端不会等到流程完成。流本身应该执行一些需要时间的事情,然后将结果存储在会话中。
然后另一个enpoint将在任何时间返回会话中的值
但是问题是会话没有持续。
这里是我的server.js的最小版本,它再现了问题
const express = require('express');
const session = require('express-session');
const app = express();
app.use(session({
secret: 'testsecret',
name: 'testmytresure',
saveUninitialized: false,
}));
const delayedResponse = () => new Promise(resolve=> setTimeout(() => resolve(`done ${new Date()}`), 200));
const startAsyncFlow = async session => {
const result = await delayedResponse(); //if remove this call and make result static value - everything works
session.test = `Result value ${result}`;
session.save();
}
app.get('/start', (req, res) => {
startAsyncFlow(req.session);
res.json('started');
})
app.get('/check', (req, res)=> {
res.json(req.session);
})
app.listen(8081, () => console.log(`Listening on port 8081`));
我的packages.json
{
"name": "isitreallybug",
"private": true,
"scripts": {
"start": "nodemon server.js"
},
"dependencies": {
"express": "^4.17.1",
"express-session": "^1.17.0",
"nodemon": "^2.0.1"
}
}
奇怪的是:
await something()
放在“ startAsyncFlow()”的结尾-会话已更新有人可以解释发生了什么吗?为什么等待后我无法与会话交互?在此先感谢
我遇到了一些很奇怪的情况,实际上无法理解正在发生的事情。感谢您对以下原因的任何解释。我有带有express和express -...的nodejs服务器。] >>
[好,您不希望在startAsyncFlow()
请求处理程序中发送响应之前先完成/start
。因此,如果客户端立即发出另一个请求,则很可能是startAsyncFlow()
尚未完成,因此会话数据尚未保存。等待足够长的时间,可能会(如果没有被其他请求覆盖)。
也许您想要await startAsyncFlow(req.session)
,并使请求处理程序async
像这样:
const promisify = require('util').promisify;
const startAsyncFlow = async session => {
const result = await delayedResponse(); //if remove this call and make result static value - everything works
session.test = `Result value ${result}`;
session.saveAsync = promisify(session.save);
await session.saveAsync();
}
app.get('/start', async (req, res) => {
try {
await startAsyncFlow(req.session);
res.json('started');
} catch(e) {
res.status(500).send("internal error");
}
});
FYI,在进行上述更改之前,您可以使用console.log()
语句对代码进行检测,以查看两个请求的实际时间,这很可能可以阐明为什么它不起作用,并希望可以帮助您了解代码的原因以上有助于解决问题:
const delayedResponse = () => new Promise(resolve=> setTimeout(() => resolve(`done ${new Date()}`), 200)); const startAsyncFlow = async session => { console.log("startAsyncFlow 1"); const result = await delayedResponse(); //if remove this call and make result static value - everything works session.test = `Result value ${result}`; console.log("startAsyncFlow 2"); session.save(function() { console.log("startAsyncFlow 4 (done)"); }); console.log("startAsyncFlow 3"); } app.get('/start', (req, res) => { console.log("/start 1"); startAsyncFlow(req.session); console.log("/start 2"); res.json('started'); }) app.get('/check', (req, res)=> { console.log("/check 1"); res.json(req.session); });
我认为您会看到此相对顺序:
/check 1 startAsyncFlow 4 (done)
您的第二个请求在
session.save()
完成之前到达的位置,因此为什么您还不能访问已保存的会话状态。
[好,您不希望在startAsyncFlow()
请求处理程序中发送响应之前先完成/start
。因此,如果客户端立即发出另一个请求,则很可能是startAsyncFlow()
尚未完成,因此会话数据尚未保存。等待足够长的时间,可能会(如果没有被其他请求覆盖)。