Javascript 在现有对象中添加新元素
我正在使用node.js 在向客户端发送响应之前,我必须在对象中添加新元素Javascript 在现有对象中添加新元素,javascript,node.js,javascript-objects,Javascript,Node.js,Javascript Objects,我正在使用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)
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.getMatch(请求用户,函数(err,match){
对于(k=0;k这里的一些问题:
首先,k没有定义,所以您使用的k实际上是一个全局变量,这不是您想要的。您需要将其定义为“var k”
其次,您传递给user.getUserInfo()
的回调函数(可能)在将来的某个未知时间执行。此时,(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);
});
虽然可以在迭代中为您提供当前索引,但不再需要该索引。只需使用curr
值(它为您提供迭代中的当前元素)
最后,我认为这里的代码可能会在所有user.getUserInfo()调用执行之前发送响应。要实现这一点,您需要知道所有user.getUserInfo()调用何时执行
已完成。这可以通过添加变量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内部和外部”时,您是指user.getUserInfo(函数(err2,info){})的内部和外部吗?
我不确定你的背景,但我可以想到两件事
由于函数“function(err2,info)”是一个回调函数,并且是异步执行的,因此getUserInfo中使用k的上下文/堆栈是完全不同的
getUserInfo(函数(err2,info,k){})。这应该可以工作
尝试在闭包中声明要使用的k i.e var k
更新问题的另一部分
但我遇到了另一个问题。它在添加“foo”元素之前向客户端发送响应。因此,在对客户端的响应中,它只从“match”发送对象,而不发送“foo”元素
这也是因为get user info中的ur代码是异步执行的。
为此,您需要保留一个全局标志或尝试从getUserInfo中发送响应
i、 e
因为javascript是异步的,所以您将获得k的随机值。您可以使用异步,而不是使用for循环module@V31,为什么随机?调用回调时,k始终等于match.length。我想在构造用户对象时最好传输k。只需添加一个新参数,每个对象将我知道它应该使用的数组索引。但我遇到了另一个问题。它在添加“foo”元素之前向客户端发送响应。因此在对客户端的响应中,它只从“match”发送对象,而不发送“foo”元素。@user3094292请查看我回复中的最后一个片段(刚刚添加)-它解决了这个问题。谢谢@Fishy和Itay Maman。我使用了这两个答案或你的答案。谢谢你的大力帮助。干杯!但我不知道哪一个会被我标记为被接受,因为你们两个都有很好的答案。无论如何,再次感谢!@user3094292如果答案是好的,如果你接受了它或对它投了更高的票,那将是很有帮助的!!@user3094292如果答案是好的话很好,如果你接受了它或投了更高的票,将会很有帮助!!!!
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 });
}
});
});
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);
}
});