[英]Add new element in existing object
我正在使用node.js。
我必须在对象中添加新元素,然后才能向客户端发送响应。
user.getMatch(req.user, function(err, match){
for( k=0; k<match.length; k++){
var userId = {
id : match[k].match_id
};
var user = new User(userId);
console.log('k: ' + k);
user.getUserInfo(function(err2, info){
console.log('k here: ' + k);
if(info){
match[k].foo = info[0].foo;
}
});
}
var response = {
data : match
};
res.json(response);
});
我想将user.getUserInfo中的元素“ foo”添加到user.getMatch返回的对象“ match”中。 然后将所有数据发送给客户端。
但是它出错了,因为user.getUserInfo内部的“ k”不等于外部的“ k”。 我不知道为什么两个“ k”不相等。
以及执行循环后如何将响应发送给客户端。
谢谢你的帮助!
这里有些问题:
首先,没有定义k,因此您使用的k实际上是一个全局变量,不是您想要的。 您需要将其定义为“ var k”。
其次,您传递给user.getUserInfo()
的回调函数可能在将来的某个未知时间执行。 此时,您for (k ...
循环已结束,因此k
变量已经具有一个新值,因为它调用了user.getUserInfo()
时具有该值。这是棘手的部分:回调中的代码函数将使用k的最新值, 而不使用创建函数时k的值。
您可以通过在回调函数中添加参数并使用.bind
方法将k绑定到此函数来解决此问题:
user.getMatch(req.user, function(err, match){
var k;
for(k=0; k < match.length; k++){
var userId = {
id : match[k].match_id
};
var user = new User(userId);
console.log('k: ' + k);
var callback = function(k, err2, info){
console.log('k here: ' + k);
if(info){
match[k].foo = info[0].foo;
}
}.bind(null, k);
user.getUserInfo(callback);
}
var response = {
data: match
};
res.json(response);
});
另外,最好使用.forEach
遍历数组:
user.getMatch(req.user, function(err, match){
match.forEach(function(curr) {
var userId = {
id : curr.match_id
};
var user = new User(userId);
user.getUserInfo(function(err2, info){
if(info){
curr.foo = info[0].foo;
}
}
});
var response = {
data: match
};
res.json(response);
});
尽管Array.forEach可以在迭代中为您提供当前索引,但不再需要此索引。 只需使用curr
值(在迭代中为您提供当前元素)。
最后,我认为这里的代码很可能在所有user.getUserInfo()
调用执行之前发送响应。 为了实现这一点,您需要知道何时所有user.getUserInfo()
已完成。 这可以通过添加变量numLeft
来实现,每次获得用户信息时该变量numLeft
递减。 当此变量达到零时,我们知道所有getUserInfo()
已完成,因此可以安全地将响应发送回去。
user.getMatch(req.user, function(err, match) {
var numLeft = match.length;
match.forEach(function(curr) {
var user = new User({
id : curr.match_id
});
user.getUserInfo(function(err2, info){
if(info) {
curr.foo = info[0].foo;
}
--numLeft;
if (numLeft == 0)
res.json({ data: match });
}
});
});
当您说“ k inside and outside”时,是指在user.getUserInfo(function(err2,info){})的内部还是外部?
我不确定您的情况,但是我可以想到两件事
由于函数“ function(err2,info)”是一个回调,并且是异步执行的,因此在getUserInfo中使用k的上下文/堆栈完全不同。 所以尝试在调用ie时传递k
user.getUserInfo(function(err2,info,k){})。 这应该工作
尝试在要使用的闭包中声明k即var k
更新问题的另一部分
“但是还有另一个问题。在添加“ foo”元素之前,它先向客户端发送响应。因此,在对客户端的响应中,它仅从“ match”对象发送,而没有“ foo”元素。”
这又是因为获取用户信息的内部代码是异步执行的。 为此,您需要保留一个全局标志或尝试从getUserInfo中发送响应,即
var mathLen = match.length;
user.getUserInfo(function(err2, info,k,mathLen)
{
console.log('k here: ' + k);
if(info){
match[k].foo = info[0].foo;
}
if(k==mathLen)
{
var response = {
data : match
};
res.json(response);
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.