等待后保存时,expression-session不持久

问题描述 投票:0回答:1

我遇到了一些很奇怪的情况,实际上无法理解正在发生的事情。感谢您对以下原因的任何解释。

我有带有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"
  }
}
  1. 运行npm运行开始或纱线启动
  2. 呼叫http://localhost:8081/start
  3. 呼叫http://localhost:8081/check-它不会返回任何内容,就好像会话没有更新

奇怪的是:

  • 如果我从会话参数中删除“ saveUninitialized:false”,则一切正常;>
  • 如果我删除了delayResponse并将任何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()完成之前到达的位置,因此为什么您还不能访问已保存的会话状态。

node.js express long-polling express-session
1个回答
0
投票

[好,您不希望在startAsyncFlow()请求处理程序中发送响应之前先完成/start。因此,如果客户端立即发出另一个请求,则很可能是startAsyncFlow()尚未完成,因此会话数据尚未保存。等待足够长的时间,可能会(如果没有被其他请求覆盖)。

© www.soinside.com 2019 - 2024. All rights reserved.