sql >> データベース >  >> NoSQL >> MongoDB

ループで呼び出されたDBクエリから取得したデータを返す際の問題

    promiseを使用するための一般的なルールから始めましょう:

    非同期で何かを行うすべての関数は、promiseを返す必要があります

    あなたの場合、これらはどの機能ですか? getPrayerInCatforEach コールバック、およびPrayer.find

    うーん、Prayer.find はpromiseを返しません。これはライブラリ関数であるため、変更できません。ルール2が機能します:

    そうでないすべての関数の即時ラッパーを作成します

    私たちの場合、Qのノードインターフェースヘルパーを使えば簡単です:

    var find = Q.nbind(Prayer.find, Prayer);
    

    今では約束しかないので、延期する必要はありません。 3番目のルールが機能します:

    非同期の結果で何かを行うものはすべて.thenに入ります コールバック

    …そして結果を返します。地獄、その結果は、「何か」が非同期であった場合でも約束になる可能性があります!これで、完全なコールバック関数を書くことができます:

    function getPrayerCount(data2) {
        var id = data2.id;
        return find({prayerCat:id})
    //  ^^^^^^ Rule 1
        .then(function(prayer) {
    //  ^^^^^ Rule 3
            if (!prayer)
                data2.prayersCount = 0;
            else
                data2.prayersCount = prayer.length;
            return data2;
    //      ^^^^^^ Rule 3b
        });
    }
    

    さて、もう少し複雑なものがあります。それはループです。 getPrayerCount()を繰り返し呼び出す 複数のpromiseを取得します。その非同期タスクは並行して実行され、不明な順序で解決されます。それらすべてを待ちたいのです。つまり、各タスクが終了したときにすべての結果で解決される約束を取得します。

    このような複雑なタスクについては、独自の解決策を考え出そうとしないでください。

    ライブラリのAPIを確認してください

    そしてそこにQ.allがあります 、これはまさにこれを行います。 getPrayerInCatを書く 今は簡単です:

    function getPrayerInCat(data) {
        var promises = data.map(getPrayerCount); // don't use forEach, we get something back
        return Q.all(promises);
    //  ^^^^^^ Rule 1
    }
    

    Q.allの配列で何かをする必要がある場合 解決するには、ルール3を適用するだけです。




    1. Ubuntu上のMongoDBはサービスとして起動せず、ログには何も記録されません

    2. LogstashWebUIが起動しない

    3. Mongoコレクションの特殊文字の操作

    4. Jacksonを使用して1つのクラスを2つの異なる方法でシリアル化します