Я использую 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"]
В коде, который вы написали, отсутствует несколько ингредиентов, которые помогут вам отладить проблему и заставить ее функционировать правильно.
Операция возвращает объект с двумя аргументами: { 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}`)
}
}
Просто добавьте условия к current
:
if (current > value) {
return { name: { first: 'Ada', last: 'Lovelace' } };
} else {
return; // Abort the transaction.
}