2013-11-04 41 views
9

是否有可能在云代码中执行嵌套查询?在云代码中使用JavaScript的嵌套查询(Parse.com)

我希望能够像做

var adList = []; 
var query2 = new Parse.Query("QR"); 
var query = new Parse.Query("Campaigns"); 
query.equalTo("isFeatured", true); 

query.find({ 
success: function(results) { 
    for (var i=0; i<results.length; i++){ 
     var ad = []; 
     ad.push(results[i].get("Type")); //Adds "Type" to the ad array 
     ad.push(results[i].id);  //gets the objectID and appends it to the arrayy 

      //second INNER QUERY 
     query2.equalTo("abc", true); 
     adList.push(ad); 
     query2.first({ 
      success: function(results){ 
       adList.push(5); 
      }, 
      error: function(){ 
       response.error("inner fail"); 
      } 
     }); 

    } 

    response.success(adList); //adds all ad arrays to adList array 
}, 
error: function(){ 
    response.error("failed"); 
} 
}); 

我试着这样做,但内部查询永远不会执行。为什么?

回答

14

第二个查询是异步的,所以将它包装在for中将不起作用。

response.success在第二个查询完成之前触发,因此您在实际等待结果之前返回。我会告诉你在第二个successquery2回调内部移动response.success,但是由于您在for内部同步运行异步操作,所以您将在第一个success中发送响应。

不要在循环内运行异步操作。它不起作用。

我不确定你在这里试图完成什么,但是如果你想作为结果进行多次查询,你必须为每个调用实例化一个新的Query

同样,我不知道究竟是什么你正在尝试做的,但这里有一个方法,你可以做这样的事情:

var adList = []; 
    var query = new Parse.Query("Campaigns"); 
    query.equalTo("isFeatured", true); 

    query.find({ 
     success: function(results) { 
      var queries = []; 

      for (var i=0; i<results.length; i++){ 
       var query2 = new Parse.Query("QR"); 
       query2.equalTo("abc",true); 

       var ad = []; 
       ad.push(results[i].get("Type")); 
       ad.push(results[i].id); 
       adList.push(ad); 
       queries.push(query2); 
      } 

      var totalLength = results.length; 

      function makeQueries(qs){ 
       qs.shift().first({ 
        success: function(currentResult) { 
         // do stuff with currentResult 
         if(qs.length){ 
          makeQueries(qs); 
         } else { 
          console.log('We successfully made ' + totalLength + ' queries') 
          // we are done with the queries 
          response.success(adList); 
         } 
        }, 
        error: function() { 
         response.error('Error in inner queries nº' + totalLength - qs.length) 
        } 
       }); 
      } 
      makeQueries(queries); 
     }, 
     error: function(){ 
      response.error("failed"); 
     } 
    }); 

酒吧记住,解析云守则让你为运行代码aprox 5/7秒,如果你有很多results,这可能会非常缓慢。 顺便说一句,看看解析的matchesQuery方法。

例从自己的文件采取:

var Post = Parse.Object.extend("Post"); 
    var Comment = Parse.Object.extend("Comment"); 
    var innerQuery = new Parse.Query(Post); 
    innerQuery.exists("image"); 
    var query = new Parse.Query(Comment); 
    query.matchesQuery("post", innerQuery); 
    query.find({ 
     success: function(comments) { 
     // comments now contains the comments for posts with images. 
     } 
    });   
+2

+1 for'matchesQuery'! –

1

我认为下面的代码可以帮助别人,

var adList = []; 
var query2 = new Parse.Query("QR"); 
var query = new Parse.Query("Campaigns"); 
query.equalTo("isFeatured", true); 

query.find().then(function(results) { 
    var _ = require('underscore'); 
    var promise = Parse.Promise.as(); 
    _.each(results, function(resultObj) { 
     var ad = []; 
     ad.push(resultObj.get("Type")); //Adds "Type" to the ad array 
     ad.push(resultObj.id);  //gets the objectID and appends it to the arrayy 

     //second INNER QUERY 
     query2.equalTo("abc", true); 
     adList.push(ad); 
     return query2.first().then(function(results) { 
      adList.push(5); 
     }); 
    }); 
    return promise; 
}).then(function() { 
    response.success(adList); 
}, function (error) { 
    response.error("Error "+error.message); 
}); 
0

我能凑齐了如下回答。这对我有用。遵循并行承诺的parse.com文档指南。我创建了两个promise数组。其中一个用作内部循环的promise数组。另一个用作外部循环的promise数组。

Parse.Cloud.define("getFriends", function (request, response) { 
    var _ = require('underscore.js'); 
    var queryFields = request.params.queryFields; 
    //var ClassToSearch = Parse.Object.extend("User"); 

    var promises = []; 
    var promises2 = []; 
    var FinalResult = []; 
var asyncFunc = function (userIDArray) { 
    _.each(queryFields, function (queryField) { 
     var query = new Parse.Query(Parse.User); 
     query.equalTo("yourColumnName", queryField); 
     promises.push(
     query.find().then(function (results) { 
     _.each(results, function (resultObj) { 
     //nested query 
     var ClassToSearch = Parse.Object.extend("AnotherColumn"); 
     var query2 = new Parse.Query(ClassToSearch); 
     query2.equalTo("yourColumnName", resultObj); 
     promises2.push(  
      query2.first().then(function (itinerary) { 
      FinalResults.push(itinerary); 
     })); 

     }); 
     return Parse.Promise.when(promises2); 
    }) 
     ) 
    }); 
    // Return a new promise that is resolved when all of the requests are done 
    return Parse.Promise.when(promises); 
    }; 
    asyncFunc(queryFields).then(function() { 
    console.log("all http requests were made"); 
    response.success(FinalResults); 
    }, function (error) { 
    console.log("there was some error"); 
    }); 
});