базовая транснациональная убыль - PullRequest
0 голосов
/ 27 августа 2018

У меня следующие проблемы:

Проблема с функцией обновления транзакции:

Попробуйте уменьшить текущее значение, сохраненное в пути к базе данных в реальном времени.Я пытаюсь обработать первый раз, когда транзакция вызывается, когда текущее значение равно нулю, аналогично тому, как я видел во многих ответах о увеличении .например, увеличение числа считываний и т. д.

Во всех примерах показано аналогичным образом:

    return (current || 0) + 1;

Но в моем случае мне нужно уменьшить какое-то значение только при текущемзначение больше, чем параметр.Несколько пользователей могут попытаться уменьшить одно и то же значение, поэтому мне нужно сделать это в транзакции.Вот мой код:

    seatsCountRef.transaction((current)=>{
        if ((current || 0) >= 1) {
            return (current || 0) - 1;
        } 
    })

Но уменьшение никогда не удается.Так что это моя главная проблема в пункте 1.

Моя другая проблема в пункте 1: Согласно документу, если я ничего не возвращаю, транзакция отменяется.

Я тоже так пытаюсь:

    ...
    else {
        return; // abort the transaction
    }

Но в обоих случаях я получил предупреждение о развертывании.Любой намек на это?

==== Я отрезал другую часть, потому что, как сказал Фрэнк ван Пуффелен, это был отдельный вопрос ===

Итактеперь это простой вопрос без внешних зависимостей.

Я просто хочу знать, как правильно уменьшить транзакции.

, потому что ВСЕ примеры и учебные пособия касаются увеличения, а функция обновления -просто

    return (current || 0) + 1;

, но когда я пытаюсь сделать

    if ((current || 0) >= 1) {
        return (current || 0) - 1;
    } 

, транзакция никогда не завершается успешно.

Ответы [ 2 ]

0 голосов
/ 28 августа 2018

Спасибо за ваши советы, Фрэнк ван Пуффелен,

После еще нескольких экспериментов у меня есть код, который работает для меня:

(и обрабатывает нулевой регистр)

return seatsCountRef.transaction((current)=>{
    if (current) {
        if (current >= 1) {
            return current - 1;
        }
    }
    return current;
})
0 голосов
/ 28 августа 2018

Этот код не будет работать:

seatsCountRef.transaction((current)=>{
    if ((current || 0) >= 1) {
        return (current || 0) - 1;
    } 
})

Помните, что я показал в вашем первом вопросе об этом куске кода :

..пока ваша запись не будет выполнена успешно без конфликта или вы прервете транзакцию, не вернув значение из функции обновления.

Теперь посмотрите на ваш код, зная, что при первом запускеВероятно, Firebase передает null в качестве текущего значения:

if ((current || 0) >= 1) {
    return (current || 0) - 1;
} 

Если current равно null, это превращается в:

if ((null || 0) >= 1) {
    return (null || 0) - 1;
} 

Что превращается в:

if (0 >= 1) {
    return 0 - 1;
} 

И поскольку 0 >= 1, если false, вы не возвращаете значение и, таким образом, прерываете транзакцию.

Вам нужно будет обработать этот начальный null.Даже когда ваш вариант использования говорит, что невозможно, чтобы значение даже не существовало, ваш код все равно должен будет обработать его, поскольку Firebase SDK может передать вам null в рамках своей операции.

Так какnull не может существовать в вашей базе данных, не имеет значения что вы вернете в этом случае.Все, что имеет значение, это то, что вы возвращаете что-то , чтобы убедиться, что транзакция не прервана.Например, это будет работать:

seatsCountRef.transaction((current)=>{
    if ((current || 0) >= 1) {
        return (current || 0) - 1;
    } 
    return "This will never be stored";
})

Но так как это значение никогда не будет сохранено, вы также можете просто возвратить -1, который приведет к простейшему коду:

seatsCountRef.transaction((current)=>{
    return (current || 0) - 1;
})

Если вы обеспокоены тем, что это недопустимое значение когда-либо сохраняется, вы можете отловить это в правилах безопасности и отклонить его:

"seatsCount": {
  ".validate": "newData.isNumber() && newData.val() >== 0"
}

Это на самом деле довольно хорошая практика в целом: один разВаша модель данных стабилизируется, используйте правила проверки для обеспечения ее соблюдения.Здесь это не будет иметь значения, так как вы уже говорите, что seatsCount должно существовать.Но на случай, если этого не произойдет, это правило безопасности перехватит выходные данные транзакции.

...