2015-03-03 67 views
0

我正在嘗試編寫一個分析雲代碼函數,其中參數是每個包含geoPoint成員的對象列表。對於列表中的每個項目,我將在Parse數據存儲中搜索1英里半徑內具有相同名稱的現有項目。如果該項目不存在,則創建該項目並將其保存到數據存儲。解析雲代碼geoPoint查詢Javascript語法

我的功能

/** 
* Take a list of Place and check for existence in Parse. 
* If it doesn't already exist, add it. 
* @see https://www.parse.com/questions/access-distance-on-a-geoquery 
* @param {JSON Place.PlaceSearch} 
* @return none 
*/ 
function addConvertedApiResult(placeData) { 
    for (var i = 0; i < placeData.length; i++) { 
     // look near loc for existing name 
     var loc = new Parse.GeoPoint(placeData[i].lat, placeData[i].lon) 

     var query = new Parse.Query("Place"); 
     query.withinMiles("location", loc, 1); 
     query.equalTo("name", placeData[i].name); 

     console.log("placeData[i].name:"+placeData[i].name); 
     query.find({ 
      success: function(results) { 
       // results contains a list of places that are within 1 mile 
       // and have the same name 
       console.log("results.length = "+results.length); 
       if(results.length < 1) { 
        // add the place 
        var Place = Parse.Object.extend("Place"); 
        var place = new Place(); 

        place.set("en", placeData[i].name); 
        place.set("location", loc); 
        place.set("moreInfo", placeData[i].moreInfo); 

        place.save(); 
       } 
      }, 
      error: function(error) { 
       // There was an error. 
       console.log("error = "+error.message); 
      } 
     }); 

     console.log("leaving addConvertedApiResult"); 
    } 
} 

我請求到雲功能調用addConvertedApiResult

(必須逃脫「'從Windows命令行)

curl -X POST 
-H "X-Parse-Application-Id: <key>" 
-H "X-Parse-REST-API-Key: <key>" -H "Content-Type: application/json" 
-d "{\"name\":\"Storm+Mountain\",\"lat\":44.0760,\"lon\":-103.2280,\"limit\":5,\"radius\":25}" https://api.parse.com/1/functions/getPlace 
{"result":[{"lat":43.95483,"lon":-103.36869,"moreInfo":"<apiUrl>/item.php?c=1\u0026i=3439","name":"Storm Mountain"}]} 

所得解析信息日誌

I2015-03-03T05:56:26.905Z] v99: Ran cloud function getPlace with: 
    Input: {"lat":44.0760,"limit":5,"lon":-103.2280,"name":"Storm+Mountain","radius":25} 
    Result: [{"name":"Storm Mountain","lat":43.95483,"lon":-103.36869,"moreInfo":"<moreInfoUrl>"}] 

I2015-03-03T05:56:27.434Z] placeData[i].name:Storm Mountain 

I2015-03-03T05:56:27.435Z] leaving addConvertedApiResult 

數據存儲中有4個存在的點應該返回,但它們沒有共享同一個名稱。該函數似乎不執行query.find方法。我沒有看到成功的日誌消息:或錯誤:函數。如果我理解正確,這些函數應該允許我在查詢結果上執行代碼。

如果console.log似乎不起作用,我怎麼能確認查詢沒有結果?

我一直在網上嘗試不同的語法變體。我的語法正確嗎?

謝謝。

更新

我一直對這個問題再次被激發,以瞭解Promises。不幸的是,我的情況並沒有改變。我現在從我的addConvertedApiResult函數調用這些函數。我使用Chrome開發人員工具在本地JavaScript文件中編寫的驅動程序對其進行了測試/調試,一切運行良好。但是,當我將此代碼部署到Parse Cloud時,我在調用.find()後,代碼執行似乎消失在以太網中。

我知道CC上的代碼執行是異步的,但我的印象是使用.then()函數應該克服這個限制。

我希望有人能向我解釋我錯過了什麼。

謝謝。

/** 
* Take a Place and check for existence in Parse. 
* If it doesn't already exist, add it. 
* @see https://www.parse.com/questions/access-distance-on-a-geoquery 
* @see https://parse.com/docs/js_guide#promises-chaining 
* @param {JSON Place.PlaceSearch} 
* @return none 
*/ 
function addNewPlace(place) { 
    // look near loc for already existing place with same name 
    var loc = new Parse.GeoPoint(place.lat, place.lon) 
    var query = new Parse.Query('Place'); 
    query.withinMiles('location', loc, 1); 
    query.equalTo('en', place.name); 
    query.find().then(function(results) { 
     if(results.length < 1) { 
      console.log(place.name+" does not exist") 
      var Place = Parse.Object.extend("Place"); 
      var newPlace = new Place(); 

      var loc = new Parse.GeoPoint(place.lat, place.lon) 
      newPlace.set('en', place.name); 
      newPlace.set('location', loc); 
      newPlace.set('moreinfo', place.moreinfo); 

      return newPlace.save(); 
     } 
    }); 
} 

/** 
* Take a list of Place and check for existence in Parse. 
* If it doesn't already exist, add it. 
* @see https://www.parse.com/questions/access-distance-on-a-geoquery 
* @see https://parse.com/docs/js_guide#promises-chaining 
* @param {JSON Place.PlaceSearch} 
* @return none 
*/ 
function addConvertedApiResult(placeData) { 
    var _ = require('underscore'); 

    console.log("placeData.legth:"+placeData.length); 
    _.each(placeData, function(place) { 
     addNewPlace(place); 
    }); 
} 
+0

嘗試使用調試器(Ctrl + Shift + J在Chrome - > Source選項卡中)。只需在'query.find'行放置斷點並更新頁面(或者單擊一個按鈕,實際上我不知道應該在何時運行代碼)。 – 2015-03-03 07:11:26

+0

感謝您的評論。 此代碼在Parse Service上運行,而不是在我的瀏覽器中,但您提出了一個很好的觀點。 也許我應該問,「我應該如何調試JavaScript被部署到解析雲代碼?」。 – Chad 2015-03-03 15:36:26

+0

我上面提供的代碼段在語法上是正確的。我的問題是,我花了一段時間纔想起編寫順序異步調用來自CloudCode的Parse和其他API的概念。最終,我能夠使用以下模式使用帶有一系列承諾的單個函數完成我想要的工作。 – Chad 2015-03-16 20:28:18

回答

0

我上面提供的代碼片斷在語法上是正確的。我的問題是,我花了一段時間纔想起編寫順序異步調用來自CloudCode的Parse和其他API的概念。最終,我能夠使用以下模式使用帶有一系列承諾的單個函數完成我想要的工作。

someCall(function(someObject) { 
    // do some stuff 
    return result; 

}).then(function(resultOfPrev) { 
    // do some more stuff 
    return result; 

}).then(function(resultOfPrev) { 
    // create some nested promises 

    // Create a trivial resolved promise as a base case. 
    var queryPromise = Parse.Promise.as(); 

    _.each(resultsOfPrev, function(thing) { 
     // For each item, extend the promise with a function to ... 
     queryPromise = queryPromise.then(function() { 

      var query = new Parse.Query(Thing); 
      query.equalTo("name", thing.name); 

      return query.find().then(function(result) { 

       var savePromise = Parse.Promise.as(); 
       savePromise = savePromise.then(function() { 

        var saved = false; 
        if(result.length < 1) { 
         // then save the thing 
         var newThing = new Thing(); 
         newThing.set('name', thing.name); 
         return newThing.save(); 
        } else { 
         return false; 
        } 
       }); 

       return savePromise; 
      }); 
     }); 
    }); 

    return queryPromise; 

}).then(function(resultsOfPrev) { 
    // response must not be called until 
    // the end of the chain. 
    response.success(resultsOfPrev); 

}.then(function() { 
    // i realy don't understand why but, 
    // I need this empty function at the 
    // tail of the chain. 
});