15

私の Parse Cloude コードでは、それぞれ「find()」を使用して、いくつかの連続したクエリを実行する必要があります。

例:

var promise = firstQuery.get(objectId).then(function(result1){
            return secondQuery.find();
        }).then(function(result2){
            return thirdQuery.find();
        }).then(function(result3) {

             // here I want to use "result1", "result2" and "result3"
        });

問題は、親スコープで宣言された変数に割り当てずに、最後の「then」ステートメントで「result1」と「result2」にアクセスするにはどうすればよいかということです。

なぜ私はこれを尋ねるのですか: 並列で実行するためにループで作成した一連のプロミスをネストしている場合、親スコープのトリックを使用することはできません (上記のステートメントの周りに for ループがあり、すべてのプロミスが配列に入れ、「Parse.Promise.when」を使用して評価します。それらはすべて、同時に親スコープ変数の変更を開始します。)

次の行に沿って何かを返すことができる、ある種の約束オブジェクトを作成できますか?

Parse.promise({result:result1,findResult:secondQuery.find()};

したがって、「result2」パラメーターから値を取得するには、次のようにします。

result2.result 

result2.findResult

私は自分自身を明確にすることを願っています。これを説明するのは非常に簡単ではありません。

4

3 に答える 3

25

追加のオブジェクトやラッピングを必要とせずに、クロージャーを使用してこれを行うことができます。

var promise = firstQuery.get(objectId).then(function(result1){
    return secondQuery.find()
    .then(function(result2) {
        return thirdQuery.find()
        .then(function(result3) {
            //can use result1, result2, result3 here
        });
    });
});

この「ネストされた」構文は、「連鎖」構文と機能が同じです。


コメントに基づいて編集

Promise チェーンが長く複雑で、ネストされた構文が扱いにくくなる場合、ロジックはおそらく、独自の関数への抽象化に値するほど複雑です。

function complexQuery(objectId) {
    var results = {};
    return firstQuery.get(objectId).then(function(result1) {
        results.result1 = result1;
        return secondQuery.find();
    })
    .then(function(result2) {
        results.result2 = result2;
        return thirdQuery.find();
    })
    .then(function(result3) {
        results.result3 = result3;
        return results;
    });
}

complexQuery(objectId)
.then(function (results) {
    //can use results.result1, results.result2, results.result3
});

個人的には、いじるよりも読みやすく維持しやすいと思います.bind

于 2014-08-12T00:24:24.880 に答える
13

親スコープのトリックは使用できません

さて、他の両方の答えがこれを行うので、そうでない解決策を提案させてください。解決済みの promise を渡すことができます。これには、ネストやクロージャーがないという追加の利点もあります。

これは、Promise はすでに値のプロキシであるという概念に基づいているため、実際に長いチェーンを 1 つ作成する必要はありません。

var firstObject = firstQuery.get(objectId);
var secondObject = firstObject.then(secondQuery.find.bind(secondQuery));
var thirdObject = secondObject.then(thirdQuery.find.bind(thirdQuery));
Promise.all(firstObject, secondObject, thirdObject).then(function(r1, r2, r3){
   // here you can use "r1", "r2" and "r3"
});

標準の promise では、コードを解析するのではなく、次のようになります。

Promise.all([firstObject, secondObject, thirdObject]).then(function(){
   var r1 = arguments[0], r2 = arguments[1], r3 = arguments[2]; 
   // here you can use "r1", "r2" and "r3"
});

ブルーバードを使用する.spreadと、ショートカット.bindまたは実際のコンテキストに使用できます。絶対に 1 つのチェーンを作成する必要がある場合は、Promise.all を使用して複数の promise を返すことでコンテキストを渡すことができますが、このアプローチが望ましいと思います。

于 2014-08-12T06:58:39.263 に答える
1

ネストではなく、フラット チェーン構文を維持したい場合は、親スコープのオブジェクトを使用して共有できます。

var shared = {};
var promise = firstQuery.get(objectId).then(function(result1){
    // save results to shared object
    shared.result1 = result1;
    return secondQuery.find();
}).then(function(result2){
    shared.result2 = result2;
    return thirdQuery.find();
}).then(function(result3) {
    // here I want to use "result1", "result2" and "result3"
    // just use shared.result1, shared.result2
});
于 2014-08-12T02:09:55.900 に答える