我是异步编程的新手,正在努力了解以下内容:
下面的代码//DB Load Users工作正常下面的代码//New user to DB确实写了一个新用户到mysql数据库,但是在呈现之前没有刷新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服务器端完全运行,将新条目推到数组的末尾。所以我认为这是我缺乏对异步计时的理解。
问题是你的范围: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);
});
})
}
然而,还有第二个问题。代码的结构方式有几个问题。首先,因为没有最终的回调,你将永远不会返回一个不存在的路由。您可能希望在代码的结尾处这样做:
app.use((req, res, next) => {
res.status(404).send( "This page does not exists" );
})
如果服务器找不到可以处理请求的有效方法,上面的代码将输出404页面。
现在它挂起的原因是因为你只注册你的get /
路由在你的post /
路由的回调。因此,除非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)
没有做任何事情-旁边没有,因此您的服务器将挂起,因为没有发送回响应。通常直到超时发生。