繁体   English   中英

在javascript中的promise-aware for循环中更新对象属性时出现问题

[英]Problem updating object properties inside a promise-aware for loop in javascript

我在 Javascript 的 for 循环中访问更新的对象属性时遇到问题。

let distribution = await ctx.db.query.distribution(
      {
        where: {
          id,
        },
      },
      `
    {
      id
      clients {
        id
        wallet {
          amount
        }
      }
    }`,
  );

let count = 0;

for (const client of distribution.clients) {
   await ctx.db.mutation.updateWallet({
       where: {
         id: client.id,
       },
       data: {
         amount: client.wallet.amount + someAmount,
       },
    });
    distribution.clients[count].wallet.amount = client.wallet.amount + someAmount;
    count++;
  }

在上面的代码中,我执行了一个 graphQL 查询来获取与分布相关的所有信息。 然后我想遍历关联的客户端数组并更新每个客户端的钱包。 同一个客户端可能在这个数组中出现多次,每次都必须更新他们的钱包。

当钱包在上一次迭代中已经更新时,就会出现问题。 当我尝试第二次更新金额时,client.wallet.amount 反映的是钱包的初始值,而不是第一次更新后的值。

显然,分发对象的属性 clients[count].wallet.amount 不会在每次迭代后更新。 我认为 javascript 对象是通过引用传递的,因此应该在每次迭代后更新对象。

有人可以向我解释为什么分发对象属性没有被更新以及我如何正确更新它?

仅供参考:我不能使用其他循环,如 forEach,因为它不是承诺感知的,也不假设 async/await

当钱包在上一次迭代中已经更新时,就会出现问题。

每个钱包对象在循环运行时只修改一次。 数组中的两个或多个钱包对象可能代表数据库中的同一行,但它们仍然是不同的对象——改变一个不会改变另一个。

const wallets = [
  { id: 1, amount: 0 },
  { id: 2, amount: 0 },
  { id: 1, amount: 0 },
]
for (const wallet of wallets) {
  wallet.amount = wallet.amount + 5
}
console.log(wallets[0]) // { id: 1, amount: 5 }
console.log(wallets[1]) // { id: 2, amount: 5 }
console.log(wallets[2]) // { id: 1, amount: 5 }

请注意,我们根本不需要使用count变量。 因为const wallet是对数组中原始对象的引用,如果我们修改它,就是修改原始对象。

如果您需要按 ID 跟踪金额,则需要实现该逻辑。 例如:

const wallets = [
  { id: 1, amount: 0 },
  { id: 2, amount: 0 },
  { id: 1, amount: 0 },
]
const amountsById = {}
for (const wallet of wallets) {
  amountsById[wallet.id] = (amountsById[wallet.id] || wallet.amount) + 5
}
const updatedWallets = wallets.map(wallet => ({
  ...wallet,
  amount: amountsById[wallet.id],
}))
console.log(updatedWallets[0]) // { id: 1, amount: 10 }
console.log(updatedWallets[1]) // { id: 2, amount: 5 }
console.log(updatedWallets[2]) // { id: 1, amount: 10 }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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