解析云代码 geoPoint 查询 Javascript 语法
Parse Cloud Code geoPoint Query Javascript Syntax
我正在尝试编写一个 Parse Cloud Code 函数,其中参数是一个对象列表,每个对象都包含一个 geoPoint 成员。对于列表中的每个项目,我将在 Parse 数据存储中搜索 1 英里半径内具有相同名称的现有项目。如果项目不存在,则创建项目并将其保存到数据存储。
我的函数
/**
* 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 个现有点应返回,但其中 none 个具有相同的名称。该函数似乎没有执行 query.find 方法。我没有看到来自 success: 或 error: 函数的日志消息。如果我理解正确,这些函数应该允许我对查询结果执行代码。
如果 console.log 似乎不起作用,我如何确认查询没有结果?
我一直在网上尝试此语法的不同变体。我的语法正确吗?
谢谢。
更新
我一直在研究这个问题,很高兴了解 Promises。不幸的是,我的情况没有改变。我现在从 addConvertedApiResult 函数中调用这些函数。我已经 tested/debugged 他们使用 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);
});
}
我上面提供的代码片段在语法上是正确的。不过,我的问题是,我花了一段时间才完全理解从 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.
});
我正在尝试编写一个 Parse Cloud Code 函数,其中参数是一个对象列表,每个对象都包含一个 geoPoint 成员。对于列表中的每个项目,我将在 Parse 数据存储中搜索 1 英里半径内具有相同名称的现有项目。如果项目不存在,则创建项目并将其保存到数据存储。
我的函数
/**
* 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 个现有点应返回,但其中 none 个具有相同的名称。该函数似乎没有执行 query.find 方法。我没有看到来自 success: 或 error: 函数的日志消息。如果我理解正确,这些函数应该允许我对查询结果执行代码。
如果 console.log 似乎不起作用,我如何确认查询没有结果?
我一直在网上尝试此语法的不同变体。我的语法正确吗?
谢谢。
更新
我一直在研究这个问题,很高兴了解 Promises。不幸的是,我的情况没有改变。我现在从 addConvertedApiResult 函数中调用这些函数。我已经 tested/debugged 他们使用 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);
});
}
我上面提供的代码片段在语法上是正确的。不过,我的问题是,我花了一段时间才完全理解从 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.
});