NodeJS で Firebase トランザクションを定義するたびに、常に 3 回実行されることに気付きます。最初の 2 回は null データで、最後に 3 回目は実際のデータで実行されます。これは正常/意図的ですか?
たとえば、このコード:
firebaseOOO.child('ref').transaction(function(data) {
console.log(data);
return data;
});
以下を出力します。
null
null
i1: { a1: true }
最後のアイテムのみを印刷すると予想していました。
コメントの質問に答えるには、コールバックと同じです:
firebaseOOO.child('ref').transaction(function(data) {
console.log(data);
return data;
}, function(error, committed, snapshot) {
if (error)
console.log('failed');
else if (!committed)
console.log('aborted');
else
console.log('committed');
console.log('fin');
});
次の出力が得られます。
null
null
i1: { a1: true }
committed
fin
質問を投稿する前にトランザクションがどのように機能するかの詳細を読んだので、次のように applyLocally を false に設定してみました。
firebaseOOO.child('ref').transaction(function(data) {
console.log('hit');
return data;
}, function(){}, false);
しかし、それでも 3 回ヒットするので (再確認しただけです)、何か違うと思いました。トランザクションの前に「値」を取得すると、1回しかヒットしないという点で期待どおりに「機能」し、applyLocallyの設定に関係なく、applyLocallyが何をするのかわかりません。これが、取引前に値を取得するという意味です。
firebaseOOO.child('ref').once('value', function(data) {
console.log('1');
firebaseOOO.child('ref').transaction(function(data) {
console.log('2');
return data;
});
});
出力:
1
2
@Michael: この動作をどのように利用できますか? トランザクションは主に、データ自体を使用してそれ自体を変更するためのものです。これは、プロトタイプのインクリメント ++ シナリオです。したがって、既存の 10 の値に 1 を追加し、11 の結果を処理し続ける必要がある場合、最初の 2 回の関数のヒットで、処理する必要がある 1 という誤った結果が得られ、最終的に次の正しい結果が得られます。 3打目で11。これら2つの最初の1をどのように利用できますか? もう 1 つのシナリオ (これにトランザクションを使用するべきではないかもしれませんが、期待どおりに機能した場合はよりクリーンなコードになります) は、値がまだ存在しない場合に値を挿入することです。トランザクションが 1 回しかヒットしない場合、null 値は値が存在しないことを意味するため、たとえば、その場合はカウンターを 1 に初期化し、それ以外の場合は値に 1 を追加します。ノイズの多いヌルで、
これらすべてからのポイントは、単純に「一度」のパターンを頻繁に使用することです。
1 回限りの取引パターン:
firebaseOOO.child('ref').once('value', function(data) {
console.log('1');
firebaseOOO.child('ref').transaction(function(data) {
console.log('2');
return data;
});
});