从Cloud Code Function返回基于objectId的Parse.User对象列表

时间:2015-08-18 15:00:07

标签: javascript asynchronous parse-platform promise cloud-code

这是我的云代码功能:

Parse.Cloud.define("nearby", function (request, response) {
    nearby(request.params.sourceId, {
      success: function(answer) {
          var values = Object.keys(answer.end_result).map(function(key) {
              nearby = answer.end_result[key];

              nearby.near = new Parse.User({id:nearby.nearId})

              return nearby;
          });

          response.success(values);
      },
      error: function(error) {
        response.error(error);
      }
    });
})

从REST API调用

curl -X POST   -H "X-Parse-Application-Id: ..."  -H "X-Parse-REST-API-Key: ..."  -H "Content-Type: application/json"  -d '{ "sourceId": "jQsulDGk8Z" }'  https://api.parse.com/1/functions/nearby | python -m json.tool

按预期返回JSON:

{
    "result": [
        {
            "distance": 3,
            "near": {
                "__type": "Object",
                "className": "_User",
                "objectId": "aPWY5YP89A"
            },
            "nearId": "aPWY5YP89A",
            "sourceId": "jQsulDGk8Z",
            "updateAt": {
                "__type": "Date",
                "iso": "2015-08-18T14:48:28.344Z"
            }
        },
        {
            "distance": 2,
            "near": {
                "__type": "Object",
                "className": "_User",
                "objectId": "GHm78KVb9r"
            },
            "nearId": "GHm78KVb9r",
            "sourceId": "jQsulDGk8Z",
            "updateAt": {
                "__type": "Date",
                "iso": "2015-08-18T14:48:22.738Z"
            }
        }
    ]
}

如何返回完全填充的用户对象而不仅仅是在代码创建的指针中?由于Parse.User查询是异步的,因此当您有多个可变数量的用户objectId要查询时,只是阻塞并等待对象填充不起作用。

我需要某种同步,我假设所有可能的用户查询。

1 个答案:

答案 0 :(得分:0)

令人高兴的是,您的NearBy模型将指针包含在用户表中。 include可以在NearBy查询中急切地抓取该指针的结尾...

function queryNearby(userId, sourceColumn, nearColumn, callback) {
    var query = new Parse.Query(NearBy);
    query.include("near");
    // ...

有一些不那么令人高兴的消息,但并不是立即感到不快:如果需要另一个查询 - 或者另一个异步操作 - 你会在2-3级回调间接中构建它。你对承诺的想法是正确的。考虑重构您的函数以始终返回promises并使用从SDK返回的解析承诺。

修改为了详细说明使用承诺,以下是修改代码以使用承诺的示例。

我们的想法是,我们拥有创建和返回承诺的函数,而不是传递回调函数和嵌套N级深度N级操作,我们拥有创建和返回承诺的函数。

现在函数nearby返回一个promise,因为它返回函数queryNearBySourceId返回的promise。如果您进一步遵循链,该函数也会返回一个承诺。最终,函数findNearby返回Parse.Query.find()返回的承诺。注意没有函数传递或调用回调函数。

// call this function like this:
// nearby("some_source_id").then(function(result) {}, function(error) {});
// the result passed to the resolution function will be the object returned by nearby()

function nearby(sourceId) {
    return queryNearBySourceId(sourceId).then(function(answer) {
        // see the end of function queryNearby: I modified it to answer a single object
        var nearbyId_answer = answer;
        var nearId_runtime = answer.runtime_seen_updates;
        var end_result = {}

        _.each(sourceId_answer, function(value, key) {
            end_result[key] = value
        });

        _.each(nearbyId_answer, function(value, key) {
            if (!(key in end_result)) {
                end_result[key] = value
            }
        });

        return {"end_result" : end_result, 
                "sourceId_answer" : sourceId_answer, 
                "sourceId_runtime" : sourceId_runtime, 
                "nearbyId_answer" : nearbyId_answer, 
                "nearId_runtime" : nearId_runtime
                };
    });
}

function queryNearBySourceId(sourceId) {
    // console.error("******** queryNearby -- queryNearBySourceId")
    return queryNearby(sourceId, "source", "near")
}

function queryNearByNearId(nearId) {
    // console.error("******** queryNearby -- queryNearByNearId")
    return queryNearby(nearId, "near", "source")
}

function queryNearby(userId, sourceColumn, nearColumn) {
    // console.error("queryNearby(" + userId + "," + sourceColumn + "," + nearColumn + ")")
    var user = new Parse.User({id:userId});
    var lastValid = moment().subtract(5, 'minutes').toDate();
    return findNearby(user, lastValid, nearColumn).then(function(results) {
        // Model: { near : distance }
        var answer = {}
        // Model: { near : updateAt }
        var runtime_seen_updates = {}

        for (var i = 0; i < results.length; i++) {
            var nearby_entry = results[i];
            var source = nearby_entry.get(sourceColumn)
            var sourceId = source.id
            var distance = nearby_entry.get("distance")
            var updateAt = nearby_entry.updatedAt
            var o = { "sourceId" : sourceId, "near" : near, "distance" : distance, "updateAt" : updateAt }

            // console.error("queryNearby :: " + JSON.stringify(o))

            // Our goal is to find the most recent entry
            if (nearId in runtime_seen_updates) {
                // console.error("queryNearby (in runtime_seen_updates) :: " + nearId + "=" + JSON.stringify(o))
                runtime_seen_updates_updateAt = runtime_seen_updates[nearId]
                if (runtime_seen_updates_updateAt < updateAt) {
                    runtime_seen_updates[nearId] = updateAt
                    answer[nearId] = o
                }
            } else {
                // console.error("queryNearby (first) :: " + nearId + "=" + JSON.stringify(o))
                runtime_seen_updates[nearId] = updateAt
                answer[nearId] = o
            }
        }
        // rather than returning two objects, I added the 'runtime_seen_updates' attribute to the answer object
        answer.runtime_seen_updates = runtime_seen_updates;

        return answer;
    }, function(error) {
        alert("Error: " + error.code + " " + error.message);
        return error;
    });
}

function findNearby(user, date, nearColumn) {
    var query = new Parse.Query(NearBy);    
    query.equalTo(sourceColumn, user); // be we search which devices saw us.
    query.greaterThan("updatedAt", date);
    query.descending("updatedAt");
    query.include(nearColumn);  // important!
    return query.find();
 }

在编辑时,我注意到了一些方法可以进一步改进这些代码,但我限制自己重构承诺,因为我希望你能够认识到原始中的单一想法变化。