【问题标题】:Javascript variable inside loop is undefined [duplicate]循环内的Javascript变量未定义[重复]
【发布时间】:2014-11-16 21:32:04
【问题描述】:

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

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' }

【问题讨论】:

  • 我也尝试使用 accountID 作为非全局变量,但每个用户都变得未定义。
  • 您定义的函数是指AccountID,它不是函数本身的本地。所以它会加载函数运行时的任何值。因为这可能是在您的 for 循环完成之后,所以它始终是循环完成时 accountID 的值 - 即最后一个用户的值。
  • 如果您将 AccountID 设置为包含 for 循环的函数的本地,那么当计费函数运行时,其他函数已完成,因此 AccountID 未定义

标签: javascript arrays json variables sails.js


【解决方案1】:

只需创建一个闭包,这样您就可以保持您正在重申的“i”的范围,并且您应该做得很好。因为你在循环,“i”的值是最后一个设置的值,所以创建一个闭包 - 为你的值创建一个有围墙的花园。有关解释,请参阅 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))
  }

【讨论】:

    【解决方案2】:

    这是因为您正在执行异步函数调用,如下所示。

    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. i 设置为 0
    2. 为users[0].stripeID调用stripe,在函数处理过程中,我们不等待,继续执行步骤(3)。
    3. i 设置为 1
    4. 为 users[1].stripeID 调用stripe,在处理此函数调用时,我们无需等待,继续执行步骤 (5)。
    5. 此时我们已经完成了 for 循环。
    6. 哦,现在函数调用(2)完成了,我们做回调函数。在回调中,我们引用了accountID,也就是当前的accountID,其实就是我们最近在第(4)步设置的accountID。
    7. 现在第 (4) 步完成了,所以我们进行回调并显示当前的 accountID,即最近的 accountID,这也是我们在第 (4) 步中得到的那个。

    好的,我们如何解决这个问题?

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-02
      • 2012-04-30
      • 2018-05-17
      • 1970-01-01
      • 2016-12-26
      • 1970-01-01
      • 2016-06-16
      • 1970-01-01
      相关资源
      最近更新 更多