节点js:-for循环中的空值错误
node js :-null value error in for loop
您好,我是 nodejs 的新手,我正在尝试实施一个项目,我们必须在该项目中创建事件管理站点..我们正在为特定用户向页面添加事件。
现在的问题是我卡在了这一点上:-
exports.getDashBoard=function(req,res){
var eventList=[];
for(var i=0;i<req.user.invites.length;i++)
{
Event.find({_id:req.user.invites[i]},function(err,events){
if(err)
{
console.log(err);
}
else
{
eventList.push(events[0]);
console.log(eventList);
// shows value inside the array as wanted
}
});
}
console.log(eventList);
// shows null value why? the variable is in the scope as its declaration
res.render('dashboard');
};
说明:
我创建了一个函数,其中每次调用该函数时都声明并初始化了变量 eventList。我在内部函数中使用了这个变量 eventList 来更新它的值并连接到以前的值。 console.log 表明当我尝试在内部函数是 doenst 工作,我得到一个初始化的空数组变量的范围是局部的,在主函数中并且在内部函数内部可见但是当我在内部函数之后使用它时,即在 for 循环之外,数组显示 null价值
怎么办?
下图:-
我创建了一个函数,其中每次调用函数时都声明并初始化了变量 eventList。我在内部函数中使用了这个变量 eventList 来更新它的值并连接到 previoys 值。 console.log 显示当我尝试在内部函数是 doenst 工作,我得到一个空数组作为初始化变量的范围是局部的在主函数中并且在内部函数内部可见但是当我在内部函数之后使用它时消失
怎么办?
您在 eventList
实际填充之前打印它。您在 Event.find
回调中将项目附加到 eventList
,当您执行外部 console.log(eventList);
.
时,这些项目可能尚未执行
编辑:
要在调用所有回调后打印集合,您可以检查回调是否处于最后一次迭代中,如果是,则打印 eventList
。
if(i===(req.user.invites.length-1)){
console.log(eventList);
}
您 could/should 还考虑了更详细的内容 async.js or some promise library (as Q)。
使用 async.js 你的代码看起来像(未测试):
async.eachSeries(req.user.invites, function (invite, callback) {
Event.find({_id:invite}, function(err,events){
if(err) {
console.log(err);
throw err;
} else {
eventList.push(events[0]);
console.log(eventList);
}
}
}, function (err) { // called once all iteration callbacks have returned (or an error was thrown)
if (err) { throw err; }
console.log(eventList); // Final version of eventList
});
Console.log 在循环结束之前被调用。
您可以在内部函数中检查最后一个循环并在为真时调用:
if(err)
{
console.log(err);
}
else
{
eventList.push(events[0]);
console.log(eventList);
// shows value inside the array as wanted
// Check if its the last loop, if so, print eventList
if(i==(req.user.invites.length-1)){
console.log(eventList);
}
}
shows null value why? the variable is in the scope as its declaration
for(var i=0;i<req.user.invites.length;i++)
{
// time taking task. probably db call.
}
console.log(eventList);
这是因为js是异步的。
在您的 for 循环中,它们存在一个耗时的任务,因此一旦 for 循环迭代结束,js 指针将移动到下一行 (console.log)。注意:只有迭代已经结束,但任务仍在进行中,它们的回调将在这些任务完成后调用。
模拟:
function(){
for(var i =0;i<5;i++){
setTimeout(function(){
console.log('time taking task is over now.');
}, 100);
}
console.log('I am after for loop');
}
在这里,输出如下:
I am after for loop
time taking task is over now.
time taking task is over now.
time taking task is over now.
time taking task is over now.
time taking task is over now.
简而言之,您需要通过确定哪些所有任务都是耗时的任务以及哪些所有任务都依赖于它们来管理您的工作流程。将所有这些依赖任务放在任务的回调中(这种方法虽然解决了问题,但随着需求的扩展,这会产生新的问题 Callback hell/pyramid of doom. See promises,因为即将到来的回调地狱)。
此外,您还可以使用 async 等工作流管理库,它将为您管理工作流。
您好,我是 nodejs 的新手,我正在尝试实施一个项目,我们必须在该项目中创建事件管理站点..我们正在为特定用户向页面添加事件。
现在的问题是我卡在了这一点上:-
exports.getDashBoard=function(req,res){
var eventList=[];
for(var i=0;i<req.user.invites.length;i++)
{
Event.find({_id:req.user.invites[i]},function(err,events){
if(err)
{
console.log(err);
}
else
{
eventList.push(events[0]);
console.log(eventList);
// shows value inside the array as wanted
}
});
}
console.log(eventList);
// shows null value why? the variable is in the scope as its declaration
res.render('dashboard');
};
说明: 我创建了一个函数,其中每次调用该函数时都声明并初始化了变量 eventList。我在内部函数中使用了这个变量 eventList 来更新它的值并连接到以前的值。 console.log 表明当我尝试在内部函数是 doenst 工作,我得到一个初始化的空数组变量的范围是局部的,在主函数中并且在内部函数内部可见但是当我在内部函数之后使用它时,即在 for 循环之外,数组显示 null价值 怎么办?
下图:- 我创建了一个函数,其中每次调用函数时都声明并初始化了变量 eventList。我在内部函数中使用了这个变量 eventList 来更新它的值并连接到 previoys 值。 console.log 显示当我尝试在内部函数是 doenst 工作,我得到一个空数组作为初始化变量的范围是局部的在主函数中并且在内部函数内部可见但是当我在内部函数之后使用它时消失
怎么办?
您在 eventList
实际填充之前打印它。您在 Event.find
回调中将项目附加到 eventList
,当您执行外部 console.log(eventList);
.
编辑:
要在调用所有回调后打印集合,您可以检查回调是否处于最后一次迭代中,如果是,则打印 eventList
。
if(i===(req.user.invites.length-1)){
console.log(eventList);
}
您 could/should 还考虑了更详细的内容 async.js or some promise library (as Q)。 使用 async.js 你的代码看起来像(未测试):
async.eachSeries(req.user.invites, function (invite, callback) {
Event.find({_id:invite}, function(err,events){
if(err) {
console.log(err);
throw err;
} else {
eventList.push(events[0]);
console.log(eventList);
}
}
}, function (err) { // called once all iteration callbacks have returned (or an error was thrown)
if (err) { throw err; }
console.log(eventList); // Final version of eventList
});
Console.log 在循环结束之前被调用。
您可以在内部函数中检查最后一个循环并在为真时调用:
if(err)
{
console.log(err);
}
else
{
eventList.push(events[0]);
console.log(eventList);
// shows value inside the array as wanted
// Check if its the last loop, if so, print eventList
if(i==(req.user.invites.length-1)){
console.log(eventList);
}
}
shows null value why? the variable is in the scope as its declaration
for(var i=0;i<req.user.invites.length;i++)
{
// time taking task. probably db call.
}
console.log(eventList);
这是因为js是异步的。
在您的 for 循环中,它们存在一个耗时的任务,因此一旦 for 循环迭代结束,js 指针将移动到下一行 (console.log)。注意:只有迭代已经结束,但任务仍在进行中,它们的回调将在这些任务完成后调用。
模拟:
function(){
for(var i =0;i<5;i++){
setTimeout(function(){
console.log('time taking task is over now.');
}, 100);
}
console.log('I am after for loop');
}
在这里,输出如下:
I am after for loop
time taking task is over now.
time taking task is over now.
time taking task is over now.
time taking task is over now.
time taking task is over now.
简而言之,您需要通过确定哪些所有任务都是耗时的任务以及哪些所有任务都依赖于它们来管理您的工作流程。将所有这些依赖任务放在任务的回调中(这种方法虽然解决了问题,但随着需求的扩展,这会产生新的问题 Callback hell/pyramid of doom. See promises,因为即将到来的回调地狱)。
此外,您还可以使用 async 等工作流管理库,它将为您管理工作流。