简体   繁体   English

在现有对象中添加新元素

[英]Add new element in existing object

I am using node.js. 我正在使用node.js。

I have to add new elements in the object before to send a response to client. 我必须在对象中添加新元素,然后才能向客户端发送响应。

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);
});

I want to add an element "foo" from user.getUserInfo to the object "match" that was returned by user.getMatch. 我想将user.getUserInfo中的元素“ foo”添加到user.getMatch返回的对象“ match”中。 And then send all the data as response to the client. 然后将所有数据发送给客户端。

But it got an error because "k" inside of user.getUserInfo is not equal to the "k" outside. 但是它出错了,因为user.getUserInfo内部的“ k”不等于外部的“ k”。 I do not know why the both "k" are not equal. 我不知道为什么两个“ k”不相等。

And how will I send a response to the client after performing the loop. 以及执行循环后如何将响应发送给客户端。

Thanks for your help! 谢谢你的帮助!

Some problems here: 这里有些问题:

First, k is not defined so the k you're using is actually a global variable which is not what you want. 首先,没有定义k,因此您使用的k实际上是一个全局变量,不是您想要的。 You need to define it as 'var k'. 您需要将其定义为“ var k”。

Second, the callback function you're passing to user.getUserInfo() is (probably) executed at some unknown time in the future. 其次,您传递给user.getUserInfo()的回调函数可能在将来的某个未知时间执行。 At this point your loop for (k ... has already finished so the the k variable already has a new value since the value that it had when you called user.getUserInfo() . And here's the tricky part: the code inside your callback function will use k's most recent value. It will not use the value that k had when the function was created. 此时,您for (k ...循环已结束,因此k变量已经具有一个新值,因为它调用了user.getUserInfo()时具有该值。这是棘手的部分:回调中的代码函数将使用k的最新值, 而不使用创建函数时k的值。

You can solve this by adding a parameter to your callback function and binding k to it using the .bind method: 您可以通过在回调函数中添加参数并使用.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);
});

Also, you'd be better off by using .forEach for iterating over an array: 另外,最好使用.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);
});

Although Array.forEach can give you your current index in the iteration, this is no longer needed. 尽管Array.forEach可以在迭代中为您提供当前索引,但不再需要此索引。 simply use the curr value (which gives you the current element in the iteration). 只需使用curr值(在迭代中为您提供当前元素)。

Finally, I think the code here is likely to send the response before all user.getUserInfo() calls have been executed. 最后,我认为这里的代码很可能在所有user.getUserInfo()调用执行之前发送响应。 To achieve that you need to know when all user.getUserInfo() have been completed. 为了实现这一点,您需要知道何时所有user.getUserInfo()已完成。 This can be achieved by adding a variable numLeft which is decremented each time we get a user info. 这可以通过添加变量numLeft来实现,每次获得用户信息时该变量numLeft递减。 when this variable reaches zero we know that all getUserInfo() have completed and it is therefore safe to send the response back. 当此变量达到零时,我们知道所有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 });
    }
  });
});

When you say "k inside and outside" do you mean inside and outside ofuser.getUserInfo(function(err2, info){})? 当您说“ k inside and outside”时,是指在user.getUserInfo(function(err2,info){})的内部还是外部?
I am not sure of your context however i can think of two things 我不确定您的情况,但是我可以想到两件事

  1. Since the function "function(err2, info)" is a callback and is executed asynchronously the context/stack in which k is used within getUserInfo is completely different. 由于函数“ function(err2,info)”是一个回调,并且是异步执行的,因此在getUserInfo中使用k的上下文/堆栈完全不同。 So try to pass k while calling ie 所以尝试在调用ie时传递k

    user.getUserInfo(function(err2, info, k){}). user.getUserInfo(function(err2,info,k){})。 This should work 这应该工作

  2. Try to declare k ie var k in the closure that you want it to be used 尝试在要使用的闭包中声明k即var k



Updating for another part of question 更新问题的另一部分
"But I got another issue.. it sends a response to client before it adds the "foo" element. So in the response to client, it only sends the object from "match" without the "foo" element." “但是还有另一个问题。在添加“ foo”元素之前,它先向客户端发送响应。因此,在对客户端的响应中,它仅从“ match”对象发送,而没有“ foo”元素。”
That is again because ur code inside get user info gets executed asynchronously. 这又是因为获取用户信息的内部代码是异步执行的。 For this you need to keep a global flag or try to send the response from within getUserInfo ie 为此,您需要保留一个全局标志或尝试从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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM