在另一个函数中请求函数响应

Requesting Function Response in another function

我有这两个函数,其中我从 "Count" 调用 "http" "http" return 承诺。我想在 "Count" 中使用 "http" 的 return 值。我现在收到的是 Undefined !!! 我缺少什么?

计数函数:

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

依赖于通过外部接口调用自己的函数并不是一个很好的做法。

既然您已经意识到您将需要相同的代码来实现不同的目的,您应该花时间重构您的代码,这样您就不需要调用 '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' 正在 returning arguments,这只是一个Array-like object.

如果 Parse.Cloud.run 在另一台虚拟机上运行你的函数,这应该没问题,但这种奇怪的行为是不通过外部调用重构和重用你的代码的另一种症状(他们的基础设施内的 HTTP 请求JSON 通过!它可能会大大降低性能并计入您的 requests/second 配额)。如果 Parse 反而做了一些魔法来直接调用您的函数,就好像它是在同一环境中定义的一样,那么您将遇到它不是实际 Array.

的问题

如果可能,您应该将该函数修改为 return 一个合适的数组。 Parse 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);
}

我想你问的是如何使用外部可调用的云函数作为更大的云过程中的一个步骤。以下是如何做到这一点:(@paolobueno 基本上是正确的,只有几个细节错误)。

首先,让我们将 'http' 云函数转换为常规 JS 函数。我们需要做的就是分解出 requestresponse 对象。 (@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 });
}

您似乎希望更新后的云函数(而不是使用来自客户端的参数)首先进行查询并将该查询的结果用作 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();
}

现在我们拥有了制作清晰、简单的 public 函数所需的一切...

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