javascript - 使用在 Node.js 上运行的 MySQL2 执行查询时出现 ERR_STREAM_WRITE_AFTER_END
问题描述
我正在实现一个功能,该功能应该在单击按钮时通过向后端发送请求并使用MySQL2更新数据库来延长用户会话的生命周期。
为此,我编写了以下前端代码:
onClose: function (oAction) {
try {
if (oAction == "YES") {
let reqURL = "/sessionExtend";
let reqData = {
session_id: sessionStorage.getItem("SessionId"),
user_id: sessionStorage.getItem("UserId")
};
let callbackOK = function (responseData) {
curr.onSuccessfulResponse(curr, responseData, "sessionExtendSuccess", "sessionExtendFail", "", false);
};
let callbackErr = function (responseData) {
curr.onErrorResponse(curr, responseData, "sessionExtendFail");
};
curr.performRequest(reqURL, reqData, callbackOK, callbackErr);
}
} catch (err) {
console.log(err);
MessageToast.show(sMsg);
}
}
请求由 app.js 接收,它使用 MySQL2 建立数据库连接并将请求转发给 DAL:
app.post("/sessionExtend", async function (req, res) {
let session_id = req.body.session_id;
let user_id = req.body.user_id;
let con = DAL.getConnection();
res.setHeader("Content-Type", "application/json");
try {
const response = await DAL.sessionExtend(con, session_id, user_id);
res.send(JSON.stringify({
"result": true,
"message": "session extended"
}));
} catch (e) {
res.send(JSON.stringify({
"result": false,
"message": "can not extend session"
}));
}
con.close();
});
DAL 模块执行 SQL 查询并应返回成功或错误的结果:
sessionExtend: async function sessionExtend(con, session_id, user_id) {
con.connect(function (err) {
try {
if (err) throw err;
con.query(qryDict.SQL_QUERIES.setUpdateExtendSession, [session_id, user_id], function (err) {
let result;
if (err) {
result = JSON.stringify({
"result": false,
"message": "failure"
});
} else {
result = JSON.stringify({
"result": true,
"message": "success"
});
}
return result;
});
} catch (err) {
let result = JSON.stringify({
"result": false,
"message": err
});
return result;
}
});
},
问题是,当我在调试器中执行此代码时,出现异常:
32) 在 PacketParser.onPacket (C:\Users\User\IdeaProjects\TST\node_modules\mysql2\lib\connection.js:75:12) 在 PacketParser.executeStart (C:\Users\User\IdeaProjects\TST\node_modules\ mysql2\lib\packet_parser.js:75:16) 在 Socket。(C:\Users\User\IdeaProjects\TST\node_modules\mysql2\lib\connection.js:82:25)
我还注意到,在调试过程中,我首先在前端得到来自后端的响应,然后才到达 DAL withing 中的断点con.query(qryDict.SQL_QUERIES.setUpdateExtendSession, [session_id, user_id], function (err) {…}
。
我的问题:
为什么我会得到
ERR_STREAM_WRITE_AFTER_END
以及如何避免它?为什么我首先在前端得到来自后端的响应,然后才到达 DAL 中的断点?我认为
await DAL.sessionExtend(con, session_id, user_id)
应该等到 DAL 上的任务完成并且承诺将得到解决。
解决方案
在CherryDT的帮助下,通过切换到 MySQL2 的 ES7 async
/ await
-wrapper 版本解决了这个问题mysql2/promise
。
为了节省其他公众的时间,最终的现成代码:
应用程序.js
app.post("/sessionExtend", async function (req, res) {
let session_id = req.body.session_id;
let user_id = req.body.user_id;
const con = await DAL.getConnection();
res.setHeader("Content-Type", "application/json");
const response = await DAL.sessionExtend(con, session_id, user_id);
res.send(JSON.stringify({
"result": response.result,
"message": response.message
}));
await con.close();
});
DAL.js
sessionExtend: async function sessionExtend(con, session_id, user_id) {
let result;
const [rows, fields] = await con.execute(qryDict.SQL_QUERIES.setUpdateExtendSession, [session_id, user_id]);
if (rows.warningStatus === 0) {
result = {
"result": true,
"message": "session extended"
};
} else {
result = {
"result": false,
"message": "session is not extended"
};
}
return result;
},
如您所见,现在代码更易于理解和维护。
PS我的建议:使用async
/ await
,它们很棒,并尽量避免回调。
推荐阅读
- list - How to search for subtext in text in Tcl?
- flutter - 如何将来自信标插件的流数据显示为小部件列表
- r - `sink(file="x.Rout", type="both", split= TRUE)` 可能吗?
- package - 如何解决 UndefVarError:
在朱莉娅? - reactjs - How to call a same modal with empty form what i have edited row data on a table row Click?
- oauth - Multiple Google Account Authorization For Single Google Drive API
- postgresql - 如何远程连接postgresql?
- python - GMM 集群 - 标记
- javascript - Async.forEach 并行运行,但它丢失了原始数组中的排序顺序
- excel - 如何从相对路径打开 Excel 对象?