Как проверить значение узла при выполнении транзакции Firebase?

Я использую regexp:

str =  'Write a program that extracts from a given text all palindromes, e.g. "ABBA", "lamal", "exe".';

var strNew = str.match(/\w+/g);

// Output: ["Write", "a", "program", "that", "extracts", "from", "a", "given", "text", "all", "palindromes", "e", "g", "ABBA", "lamal", "exe"]
0
задан Frank van Puffelen 13 July 2018 в 18:48
поделиться

2 ответа

В коде, который вы написали, отсутствует несколько ингредиентов, которые помогут вам отладить проблему и заставить ее функционировать правильно.

Операция возвращает объект с двумя аргументами: { committed, snapshot }. Очень важно, чтобы вы проверили committed логическое значение, чтобы увидеть, действительно ли транзакция что-то изменила. В вашем случае, если committed - false, вы хотите уведомить пользователя о том, что билеты недоступны.

Также обратите внимание, что current может быть null (и будет отображаться на большинстве первые прогоны транзакции). Возможно, вы захотите обработать этот случай по-другому и проверить на snapshot.exists().

Еще одна вещь, которая отсутствует, - это предложение catch. Вполне возможно, что ваша транзакция не удалась. Если это так, вы можете упустить его. Это также хороший план, чтобы вернуть вызов .set(...), чтобы убедиться, что вы поймаете и этот результат.

Еще одна вещь, которая может пойти не так, заключается в том, что какой-то другой код использует set или update для изменения данные в этом месте. Если это произойдет, транзакция будет отменена.

Что касается кода самой транзакции, это выглядит вполне нормально. Однако current || 0 не имеет большого смысла. Если текущий null и ticket_count - это положительное число (которое, я думаю, у вас есть охрана в другом месте), оно никогда не достигнет этой ветви.

Я лично изменил бы (current || 0) + increment на current - ticket_count, чтобы сделать его более читаемым, но это просто вкус.


Обновить

Вы можете получить доступ committed и snapshot:

ref.transaction(...).then(({ committed, snapshot }) => ...)

Если вы хотите повторить попытку неудачных транзакций, вы можете использовать такую ​​функцию:

async function withRetries(ref, transaction, attempts = 0) {
  try {
    const result = await ref.transaction(transaction, undefined, false)
    return result
  } catch (e) {
    if (attempts < MAX_TRANSACTION_ATTEMPTS) return withRetries(ref, transaction, attempts + 1)
    throw new Error(`transaction failed ${MAX_TRANSACTION_ATTEMPTS} times, error: ${e.message}`)
  }
}
1
ответ дан EECOLOR 17 August 2018 в 12:15
поделиться
  • 1
    Не могли бы вы более подробно объяснить, где будут возникать эти аргументы? Я проверяю документы, и я не могу их найти! – Arjun Ram 13 July 2018 в 19:56
  • 2
    Кроме того, если транзакция отменена, как мне переписать этот метод? – Arjun Ram 13 July 2018 в 19:57
  • 3
    @ArjunRam Я обновил свой ответ. Что касается документации, посмотрите внизу (где указано возвращает ) документации транзакции: firebase.google.com/docs/reference/node/… – EECOLOR 13 July 2018 в 20:03
  • 4
    Спасибо за помощь! – Arjun Ram 13 July 2018 в 20:04

Просто добавьте условия к current:

  if (current > value) {
    return { name: { first: 'Ada', last: 'Lovelace' } };
  } else {
    return; // Abort the transaction.
  }
0
ответ дан d.mares 17 August 2018 в 12:15
поделиться
  • 1
    Эй, поэтому я попробовал это. Объект JSON обновляется, но если я напишу команду return current - ticket_count, это не сработает! Почему это? – Arjun Ram 16 July 2018 в 06:08
Другие вопросы по тегам:

Похожие вопросы: