Requesting Function Response in another function

我的梦境 提交于 2020-01-17 06:32:08

问题


I have those two functions where i call "http" from "Count" the "http" return promise. I want to use the return value of "http" in "Count". What I receive now is Undefined !!! What I'm missing ?

Count Function :

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 Function :

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

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

回答1:


I think what you're asking is how to use an externally callable cloud function as a step in a bigger cloud procedure. Here's how to do it: (@paolobueno has it essentially correct, with only a couple mistakes in the details).

First, let's convert that 'http' cloud function to a regular JS function. All we need to do is factor out the request and response objects. (@paolobueno has a very good idea to use underscorejs, but I won't here because its another new thing to learn).

// 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 });
}

It looks like you want the updated cloud function -- rather than use params from the client -- to first make a query and use the results of that query as parameters to the http calling function. Here's how to do that. (Again, using @paolobueno's EXCELLENT practice of factoring into promise-returning functions...)

// 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();
}

Now we have everything needed to make a clear, simple public function...

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);
    });
});



回答2:


Relying on calling your own functions through an external interface is not a very good practice.

Now that you've realized you're going to need the same code for a different purpose, you should take the time to refactor your code such that you don't need to call the 'http' handler through 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);
}

I've taken a look at the other question and as far as the implementation of count goes, I believe you're missing the point that 'http' is returning arguments, which is only an Array-like object.

This should be okay if Parse.Cloud.run runs your function on another virtual machine, but this kind of weird behaviour is another symptom of not refactoring and reusing your code through an external call (an HTTP request inside their infrastructure with JSON passing! It might greatly reduce performance and count against your requests/second quota). If Parse instead does some magic to call your function directly as if it was defined on the same environment, you're going to have problems with it not being an actual Array.

You should modify that function to return a proper array if possible. Parse CloudCode has a version of the Underscore library:

// on http
var _ = require('underscore');
Parse.Promise.when(promises).then(function() {
  var results = _.toArray(arguments) // equivalent to Array.prototype.slice above
  response.success(results);
}


来源:https://stackoverflow.com/questions/33752377/requesting-function-response-in-another-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!