Проблема при обновлении свойств объекта в сообщении об обещании для l oop in javascript - PullRequest
1 голос
/ 14 февраля 2020

У меня проблема с доступом к обновленным свойствам объекта внутри для l oop в Javascript.

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, поскольку это не обещает в курсе и не предполагает асинхронность / ожидание

1 Ответ

0 голосов
/ 14 февраля 2020

Проблема возникает, когда кошелек уже был обновлен в предыдущей итерации.

Каждый кошелек объект изменяется только один раз при запуске l oop , Два или более объектов кошелька в массиве могут представлять одну и ту же строку в базе данных, но они по-прежнему являются различными объектами - изменение одного не изменит другого.

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 является ссылкой на исходный объект в массиве, если мы изменим его, мы изменим исходный объект.

Если вы хотите отслеживать суммы по идентификатору, вам необходимо реализовать эти логики c. Например:

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 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...