5

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;
    });
});
4

2 に答える 2

2

ここで見られる動作は、Firebase がローカル イベントを発生させ、最終的に Firebase サーバーと同期する方法に関連しています。この特定の例では、「3 回の実行」は、コードを最初に実行したときにのみ発生します。その後、状態は完全に同期され、それ以降は 1 回だけトリガーされます。この動作について詳しくは、 https ://www.firebase.com/docs/transactions.html をご覧ください(「トランザクションが実行されると、次が発生する」セクションを参照してください)。

たとえば、同じ場所に未処理の on() があり、後で同じトランザクション コードを実行すると、一度だけ実行されることがわかります。これは、トランザクションが実行される前にすべてが同期されているためです (理想的なケースでは、通常の競合などを除いて)。

于 2013-04-21T02:36:45.543 に答える