mysql 异步等待承诺的数据在快速POST呼叫时不可用

eoxn13cs  于 2023-04-04  发布在  Mysql
关注(0)|答案(1)|浏览(100)

我是异步编程的新手,并试图了解以下内容:
//DB Load Users后面的代码工作正常//New user to DB后面的代码确实向mysql DB写入了一个新用户,但在渲染之前未能刷新user中的数据。Web服务器挂起(光标计时器符号),当我重新输入url时,页面渲染,但没有新数据。只有重新启动终端才能在网页上提供数据。

//DB Load Users
const users = new Promise((resolve, reject) => {
    var sql = "SELECT username, useremail, userage, useruniqueid FROM users";
    db.query(sql, function(err, result) {
        if (err) throw err;
        resolve(result);
    });
})

//DB refresh Users
function refresh() {
    const users = new Promise((resolve, reject) => {
        var sql = "SELECT username, useremail, userage, useruniqueid FROM users";
        db.query(sql, function(err, result) {
            if (err) throw err;
            resolve(result);
        });
    })
}

//Render (express) HTML with promise resolve after DB-query - works!!
app.get("/", async(_req, res, next) => {
    try {
        res.render("home", { data: await users });
    } catch (err) {
        next(err);
    }
});


//New user to DB
app.post("/", (req, res) => {
    const inputUserName = req.body.username
    const inputUserEmail = req.body.useremail
    const inputUserAge = req.body.userage
    const inputUserUniqueId = req.body.useruniqueid

    db.query('insert into users values(?,?,?,?)', [inputUserUniqueId, inputUserName, inputUserEmail, inputUserAge], (err, result) => {
        if (err) { console.log(err) } else {
            console.log('new user added');
        }
    })
    refresh(); //update users from DB
    // wait for user-data and render webpage - does not work - no updated data and webserver hangs
    app.get("/", async(_req, res, next) => {
        try {
            res.render("home", { data: await users });
        } catch (err) {
            next(err);
        }
    });
})

当我使用手动定义的users []时,我已经完全运行了Web服务器端,将新条目推到数组的末尾。所以我假设这是我缺乏对异步计时的理解。

bhmjp9jg

bhmjp9jg1#

问题是你的范围:const users * 无法更改 *(因此:常量),即使你尝试这样做,你的作用域也是refresh函数,这意味着即使你的查询正确运行,它也不会被更新。下面的代码应该能按预期工作:

// Make users replacable by using `let`, which can be changed.
let users = new Promise((resolve, reject) => {
    var sql = "SELECT username, useremail, userage, useruniqueid FROM users";
    db.query(sql, function(err, result) {
        if (err) throw err;
        resolve(result);
    });
})

function refresh() {
   // You want to assign this new promise to the global `users` variable.
   // If you set a constant here, the result will only be
   // available within this function scope.
   // But because the global object is `let`, we can reassign it from within here.
   // Just don't _declare_ it here, only reassign it.
   users = new Promise((resolve, reject) => {
        var sql = "SELECT username, useremail, userage, useruniqueid FROM users";
        db.query(sql, function(err, result) {
            if (err) throw err;
            resolve(result);
        });
    })
}

然而,还有第二个问题。你的代码结构有几个问题。首先,由于没有final回调,你将永远不会返回一个不存在的路由。你可能想在代码的结尾这样做:

app.use((req, res, next) => {
   
    res.status(404).send( "This page does not exists" );

})

如果服务器找不到能够处理请求的方法,上面的代码将输出404页面。
现在它挂起的原因是因为您只在post /路由的回调中注册了get /路由。因此,除非post调用完成,否则get路由不可用。只需在post响应之外注册即可:

app.post("/", async (req, res, next) => {
    const inputUserName = req.body.username
    const inputUserEmail = req.body.useremail
    const inputUserAge = req.body.userage
    const inputUserUniqueId = req.body.useruniqueid

    db.query('insert into users values(?,?,?,?)', [inputUserUniqueId, inputUserName, inputUserEmail, inputUserAge], (err, result) => {
        if (err) { console.log(err) } else {
            console.log('new user added');
        }
    });

    refresh(); //update users from DB
    res.render("home", { data: await users });

});

app.get("/", async (req, res, next) => {

    try {
        res.render("home", { data: await users });
    } catch (err) {
        next(err);
    }

});

你的最后一个next(err)没有做任何事情-没有下一步,所以你的服务器将挂起,因为没有响应被发送回来。通常直到超时发生。

相关问题