Разбор облачного кода GeoPoint Query Синтаксис Javascript

Я пытаюсь написать функцию 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 существующие точки, которые должны быть возвращены, но ни одна из них не имеет одинакового имени. Функция не выполняет метод query.find. Я не вижу сообщений журнала об успехах: или ошибках: функций. Если я правильно понимаю, эти функции должны позволять мне выполнять код на результатах запроса.

Как я могу подтвердить, что запрос не дал результатов, если console.log не работает?

Я был в Интернете, пробуя различные варианты этого синтаксиса. Правилен ли мой синтаксис?

Спасибо.

Обновить

Я снова работал над этой проблемой и был рад узнать об Promises. К сожалению, моя ситуация не изменилась. Теперь я вызываю эти функции из моей функции addConvertedApiResult. Я протестировал/отладил их с помощью драйвера, написанного в локальном файле javascript с помощью инструментов Chrome Developer, все работает хорошо. Но когда я развертываю этот код в 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);
    });
}

person Chad    schedule 03.03.2015    source источник
comment
Попробуйте использовать отладчик (Ctrl+Shift+J в Chrome -> вкладка «Источник»). Просто поместите точку останова в строку query.find и обновите страницу (или нажмите кнопку, я не знаю, когда должен запускаться ваш код).   -  person Anatoliy Arkhipov    schedule 03.03.2015
comment
Спасибо за комментарий. Этот код работает в службе синтаксического анализа, а не в моем браузере, но вы затронули хорошую тему. Возможно, мне следовало спросить: «Как мне отлаживать javascript, развернутый в Parse Cloud Code?».   -  person Chad    schedule 03.03.2015
comment
Фрагменты кода, которые я предоставил выше, синтаксически правильны. Однако моя проблема заключалась в том, что мне потребовалось некоторое время, чтобы понять концепцию программирования последовательных асинхронных вызовов Parse и других API из CloudCode. В конечном итоге я смог выполнить то, что хотел, используя одну единственную функцию со строкой обещаний, используя следующий шаблон.   -  person Chad    schedule 16.03.2015


Ответы (1)


Фрагменты кода, которые я предоставил выше, синтаксически правильны. Однако моя проблема заключалась в том, что мне потребовалось некоторое время, чтобы понять концепцию программирования последовательных асинхронных вызовов Parse и других API из CloudCode. В конечном итоге я смог выполнить то, что хотел, используя одну единственную функцию со строкой обещаний, используя следующий шаблон.

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.
});
person Chad    schedule 16.03.2015