gpt4 book ai didi

javascript - Node Js/Javascript 提升,变量保持未定义

转载 作者:行者123 更新时间:2023-12-03 07:13:15 24 4
gpt4 key购买 nike

var exp = [];   
connection.query(`select *
from glossary
where ${connection.escape(word)} = word`,
function(err, rows, fields){
if(err) throw err;

if(rows.length > 0){
for (var i = 0; i < rows.length; i++) {
exp[i] = "Explanation: " + rows[i].explanation + ' ';
}

var usN = [];
for (var i = 0; i < rows.length; i++) {
connection.query("select * from users where id =" + rows[i].userID, function(err2, rows2, fields2){
if(err2) throw err2;
if(rows2.length > 0){
usN[i] = "Edited by: " + rows2[0].username;
}
});
}
response.render("gloss.jade", { user: request.session.user, logedIn: request.session.user, yourWord: word, exp: exp, users: usN});
}
}
)

usN 数组获取值但保持未定义状态,exp 数组获取值但不会重新定义。我可以请你帮我解决这个问题吗?

最佳答案

这里至少存在三个问题:

  1. 异步回调的计时问题。
  2. 您的for循环索引在异步回调内无效。
  3. 您的错误处理不会起作用,因为执行 throw从异步回调内部不会做任何有用的事情。

以下是每个问题的更多详细信息。

您的主要问题是这是一个时间问题。 connection.query()是异步的。这意味着它不会阻塞并且会在未来的某个时间完成。那么,您调用connection.query()并且其他代码继续运行。事实上,您的整个for循环从所有 connection.query() 开始运行调用,然后,一段时间后,为每个 connection.query() 调用回调。 .

因此,如果您查找 usN 的值在你的response.render()调用时,它还没有值,因为 connection.query() 都没有操作尚未完成,因此尚未调用回调。您可以可靠地使用 usN 的唯一地方值在您的 connection.query() 内打回来。因为您在 for 中多次这样做循环,您必须跟踪所有回调何时完成。

有很多不同的方法可以解决这个问题,但这里有一种方法可以用来记录 for 中有多少异步回调。循环已完成,当它们全部被调用时,您可以调用渲染。

另外,因为回调是稍后调用的,所以你的for循环索引 i在回调中也不再有效。这可以通过将其全部包装在 IIFE 中来解决,该 IIFE 为每个回调单独捕获循环计数器。

并且,尝试 if(err2) throw err2;回调内部不会做任何有用的事情,因为执行 throw在这种类型的异步回调中,只会抛出到数据库代码中,并且不会是您可以在自己的代码中的任何位置捕获的内容。相反,您必须通过某种您自己的回调来传达错误。 Promise 实际上是一种更好的通信和传播异步错误的方式。这是修复了前两项的实现(此处未更正错误处理,因为这需要一些其他结构更改):

function(err, rows, fields){       
if(err) throw err;

if(rows.length > 0){
for (var i = 0; i < rows.length; i++) {
exp[i] = "Explanation: " + rows[i].explanation + ' ';
}

var usN = [];
var cnt = 0;
for (var i = 0; i < rows.length; i++) {
(function(index) {
connection.query("select * from users where id =" + rows[i].userID, function(err2, rows2, fields2){
// ISSUE: doing a throw here does nothing useful
// as it just goes back into the async database code
// You need a better way to propagate errors
if(err2) throw err2;
if(rows2.length > 0){
usN[index] = "Edited by: " + rows2[0].username;
}
// see if this is the last callback
++cnt;
if (cnt === rows.length) {
response.render("gloss.jade", { user: request.session.user, logedIn: request.session.user, yourWord: word, exp: exp, users: usN});
}
});
})(i);
}
}
}

关于javascript - Node Js/Javascript 提升,变量保持未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36535967/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com