12

何度か、Firebaseを使用した同期関数と非同期関数で問題が発生しました。私の問題は、自分が作成した関数内で非同期のFirebase呼び出しを行う必要があることです。簡単な例として、オブジェクトの速度を計算して表示する必要があり、Firebaseに距離と時間が保存されているとします。

function calcVelocity() {
    var distance, time, velocity;

    firebaseRef.once('value', function(snapshot) {
        distance = snapshot.val().distance;
        time = snapshot.val().time;

        velocity = distance / time;
    });
    return velocity;
}

$("#velocity").html(calcVelocity());

もちろん、上記のコードはfirebaseRef.once()非同期呼び出しであるため機能しません。したがってvelocity、に到達した時点ではまだ設定されていませんreturn velocity;returnコールバック関数の内部に配置する.on()と、何も返されません。

1つの解決策は、calcVelocity()関数を非同期にすることです。

別の解決策は、同期的に読み取られるがFirebaseから非同期に更新されるFirebaseのキャッシュバージョンを保存することです。

これらのソリューションの1つは他よりも優れていますか?そして、より良い解決策はありますか?

4

3 に答える 3

9

もう 1 つのアプローチは、Promise 戦略を利用することです。jQuery には素晴らしいものがあります。

function calcVelocity() {
    var distance, time, velocity, def = $.Deferred();

    firebaseRef.once('value', function(snapshot) {
        distance = snapshot.val().distance;
        time = snapshot.val().time;

        def.resolve( distance / time );
    });
    return def.promise();
}

calcVelocity().then(function(vel) { $("#velocity").html(vel); });

nullsnapshot.val().distance;を返すとエラーが返される可能性があることにも注意してください。snapshot.val()

于 2012-07-24T18:36:44.183 に答える
8

関数を非同期にするか、最新の Firebase データをキャッシュして同期的にアクセスできるようにするかの 2 つの可能性を突き止めました。どちらを使用するかは、作成しているアプリのコンテキストを考慮して、好みと利便性の問題です。

たとえば、「アクション ゲーム」は通常、firebase のデータ変更イベントではなく、タイトなレンダリング ループによって駆動されることに気付きました。そのため、レンダー ループで使用する最新の Firebase データをキャッシュすることは理にかなっています。例えば:

var latestSnapshot = null;
firebaseRef.on('value', function(snap) { latestSnapshot = snap; });

そして、レンダー ループ (またはその他の場所) で latestSnapshot を同期的に使用できます。

于 2012-07-24T18:29:43.863 に答える
6

@Kato が提供した回答と同じアイデアですが、Firebase に組み込みのプロミスを使用すると、次のようになります。

function calcVelocity(snapshot) {
    var distance, time, velocity;

    distance = snapshot.val().distance;
    time = snapshot.val().time;

    return distance / time;
}

function getVelocity() {
return firebaseRef.once('value').then(calcVelocity);
}

getVelocity().then(function(vel) { $("#velocity").html(vel); });
于 2016-02-03T00:29:24.320 に答える