循环内的Javascript变量未定义

时间:2014-11-16 21:32:05

标签: javascript arrays json variables sails.js

我有一个循环,它获取一组用户,然后尝试获取每个用户的信息。使用下面的代码,如果我有两个用户,它会返回相同的信息(最后一个用户)两次。因此,当我尝试更新并保存用户信息时,它只保存最后用户的信息。

for (i = 0; i < users.length; i++) { 
    var amount = users[i].monthlyAmount;
    // var stripeID = users[i].stripeID;
    // if the amount charged is greater than 0, charge the customer the correct amount
    if(amount != '0') {
      var stripeID = users[i].stripeID;
      accountID =  users[i];
      // stripe function to charge customer
      stripe.charges.create({
        amount: amount,
        currency: "usd",
        customer: stripeID, 
        description: "Monthly charge"
        }, function(err, charge) {
        if (err) return (err);
        // if there are no errors with charging the customer, proceed to reset the monthly amount
        if(!err) {
          console.log(accountID);
          accountID.monthlyAmount = '0';
          accountID.save();
        }
      });
    }
  }

这是输出的结果:

{ billingInfo: 'true',
createdAt: Sun Nov 16 2014 14:05:21 GMT-0600 (CST),
email: 'a@a.com',
encryptedPassword: '*removed',
monthlyAmount: 1000,
propertyCount: 0,
stripeID: '*removed',
updatedAt: Sun Nov 16 2014 15:10:59 GMT-0600 (CST),
id: '54690381c03a265b07c99564' }
{ billingInfo: 'true',
createdAt: Sun Nov 16 2014 14:05:21 GMT-0600 (CST),
email: 'a@a.com',
encryptedPassword: '*removed',
monthlyAmount: '0',
propertyCount: 0,
stripeID: '*removed',
updatedAt: Sun Nov 16 2014 15:10:59 GMT-0600 (CST),
id: '54690381c03a265b07c99564' }

2 个答案:

答案 0 :(得分:2)

只需创建一个闭包,这样就可以保持&#34; i&#34;你重申,你应该好。因为你正在循环,所以&#34; i&#34;的价值是设置的最后一个值,因此创建一个闭包 - 一个围墙花园,为您的价值观。有关解释,请参阅Aravinds帖子

for (i = 0; i < users.length; i++) {
  (function(i){
    var amount = users[i].monthlyAmount;
    // var stripeID = users[i].stripeID;
    // if the amount charged is greater than 0, charge the customer the correct amount
    if(amount != '0') {
      var stripeID = users[i].stripeID;
      accountID =  users[i];
      // stripe function to charge customer
      stripe.charges.create({
        amount: amount,
        currency: "usd",
        customer: stripeID, 
        description: "Monthly charge"
        }, function(err, charge) {
        if (err) return (err);
        // if there are no errors with charging the customer, proceed to reset the monthly amount
        if(!err) {
          console.log(accountID);
          accountID.monthlyAmount = '0';
          accountID.save();
        }
      });
    }
  }(i))
  }

答案 1 :(得分:1)

这是因为你正在进行异步函数调用,就像这样。

for (i = 0; i < users.length; i++) { 
      stripe.charges.create({
           ...
        }, function(err, charge) {
            //when stripes.charges.create function is done, call this piece of code.
        });
}
  1. 我设为0
  2. 为用户[0] .stripeID调用
  3. stripe,当函数正在处理时,我们不等待,我们继续执行步骤(3)。
  4. 我被设置为1
  5. 为用户[1] .stripeID调用
  6. stripe,当此函数调用正在处理时,我们不等待,我们继续执行步骤(5)。
  7. 此时我们已经完成了for循环。
  8. 哦,现在函数调用(2)完成,我们执行回调函数。在回调中,我们引用的是accountID,它是当前的accountID,实际上是我们最近在步骤(4)中设置的accountID。
  9. 现在步骤(4)来了,所以我们做回调并显示当前的帐号ID,这是最近的帐号ID,这也是我们在步骤(4)中得到的帐号。
  10. 好的,我们如何解决这个问题?

    for (i = 0; i < users.length; i++) { 
        var amount = users[i].monthlyAmount;
        // var stripeID = users[i].stripeID;
        // if the amount charged is greater than 0, charge the customer the correct amount
        if(amount != '0') {
          var stripeID = users[i].stripeID;
          accountID =  users[i];
          function callback(){
            var accountID = accountID;
            return function(err, charge) {
            if (err) return (err);
            // if there are no errors with charging the customer, proceed to reset the monthly amount
            if(!err) {
              console.log(accountID);
              accountID.monthlyAmount = '0';
              accountID.save();
            };
          }
          // stripe function to charge customer
          stripe.charges.create({
            amount: amount,
            currency: "usd",
            customer: stripeID, 
            description: "Monthly charge"
            }, callback()
          });
        }
      }