2015-11-17 2 views
0

У меня есть эти две функции, где я называю «http» из «Count» «обещанием возврата». Я хочу использовать возвращаемое значение «http» в «Count». Что я получаю сейчас Undefined !!! Что мне не хватает?Запрос функции Ответ в другой функции

Count Функция:

Parse.Cloud.define('count', function(request, response) { 

var query = new Parse.Query('MyS'); 
    query.equalTo("Notify", true); 
    query.notEqualTo ("MainEventCode", '5'); 

    query.find({ 
    success: function(results) { 
     Parse.Cloud.run('http', {params : results}).then(
     function(httpResponse) { 
      console.log('httpResponse is : ' + httpResponse.length); 
      response.success('Done !'); 
     }, function(error) { 
      console.error(error); 
     }); 
    }, 
    error: function(error) { 
     response.error(error); 
    } 
    }); 
}); 

HTTP Функция:

Parse.Cloud.define('http', function(request, response) { 

var query = new Parse.Query(Parse.Installation); 
. 
. 
. 
} 
+0

где вы получаете 'undefined' как значение? –

+0

на console.log ('httpResponse is:' + httpResponse.длина); – OXXY

+0

Каково значение объекта 'httpResponse'? –

ответ

1

Я думаю, что вы спрашиваете, как использовать внешне вызываемую функцию облака как шаг в большем порядке облака. Вот как это сделать: (@paolobueno имеет это по существу правильно, только с несколькими ошибками в деталях).

Во-первых, давайте преобразуем эту облачную функцию «http» в обычную функцию JS. Все, что нам нужно сделать, это разделить request и response объектов. (@paolobueno имеет очень хорошую идею использовать underscorejs, но я не буду здесь, потому что его еще одна новая вещь, чтобы учиться).

// for each object passed in objects, make an http request 
// return a promise to complete all of these requests 
function makeRequestsWithObjects(objects) { 
    // underscorejs map() function would make this an almost one-liner 
    var promises = []; 
    for (var i = 0; i < objects.length; i++) { 
     var object = objects[i]; 
     promises.push(makeRequestWithObject(object)); 
    } 
    return Parse.Promise.when(promises); 
}; 

// return a promise to do just one http request 
function makeRequestWithObject(object) { 
    var url = 'http://185.xxxxxxx'+ object +'&languagePath=en'; 
    return Parse.Cloud.httpRequest({ url:url }); 
} 

Похоже, что вы хотите обновленную функцию облака - вместо использования Params от клиента - сначала сделать запрос и использовать результаты этого запроса в качестве параметров функции HTTP вызова. Вот как это сделать. (Опять же, ОТЛИЧНОЕ практика с использованием @ paolobueno по факторингу в обещание функций, возвращающих ...)

// return a promise to find MyS instances 
function findMyS() { 
    var query = new Parse.Query('MyS'); 
    query.equalTo("Notify", true); 
    query.notEqualTo ("MainEventCode", '5'); 
    return query.find(); 
} 

Теперь у нас есть все необходимое, чтобы сделать простую и понятную общественную функцию ...

Parse.Cloud.define('count', function(request, response) { 
    findMyS().then(function(objects) { 
     return makeRequestsWithObjects(objects); 
    }).then(function(result) { 
     response.success(result); 
    } , function(error) { 
     response.error(error); 
    }); 
}); 
+0

Это работает как charm xD. Но я знаю, что только один ответ HTTP хранится внутри обещания, хотя отправлено 4 запроса! – OXXY

+0

На самом деле обещание содержит все объекты, но я нашел только первое при достижении .then (function (result) { response.success (result); } block – OXXY

+0

это как-то связано с "_resolved" ?? – OXXY

2

Опираясь на свою собственный вызов функции через внешний интерфейс не очень хорошая практика.

Теперь, когда вы поняли, что вы будете нуждаться в один и тот же код для различных целей, вы должны взять время, чтобы реорганизовать свой код таким образом, что вам не нужно вызывать 'http' обработчик через Parse.Cloud.run():

function doHttp(params) { 
    // original implementation here 
} 

Parse.Cloud.define('http', function(request, response) { 
    doHttp(request.params) 
    .then(response.success) 
    .fail(response.error); 
} 

Parse.Cloud.define('count', function(request, response)) { 
    var query = new Parse.Query('MyS'); 
    query.equalTo("Notify", true); 
    query.notEqualTo ("MainEventCode", '5'); 

    query.find() 
    .then(doHttp) // doHttp will receive the results from `query` as its parameter 
    .then(function(httpResponses) { 
     // httpResponses is an array-like object as per the other question: 
     httpResponses = Array.prototype.slice.call(httpResponses); 
     httpResponses.forEach(function (response) { 
     console.log('httpResponse is : ' + response.length); 
     }); 
    }).fail(response.error); 
} 

Я принял взглянуть на другой вопрос, и насколько реализация count идет, я полагаю, вы пропустили точку, что 'http' возвращается arguments, который только Array-like object.

Это должно быть хорошо, если Parse.Cloud.run запускает вашу функцию на другой виртуальной машине, но это странное поведение является еще одним симптомом не рефакторинга и повторного использования кода через внешний вызов (HTTP-запрос внутри их инфраструктуры с передачей JSON! может значительно снизить производительность и подсчитать ваши запросы/вторую квоту). Если Parse вместо этого делает какую-то магию, чтобы вызвать вашу функцию напрямую, как если бы она была определена в одной и той же среде, у вас будут проблемы с тем, что она не является фактическим Array.

Вы должны изменить эту функцию, чтобы вернуть правильный массив, если это возможно. Анализировать CloudCode имеет версию Underscore библиотеки:

// on http 
var _ = require('underscore'); 
Parse.Promise.when(promises).then(function() { 
    var results = _.toArray(arguments) // equivalent to Array.prototype.slice above 
    response.success(results); 
} 
Смежные вопросы