这是我的云代码功能:
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要查询时,只是阻塞并等待对象填充不起作用。
我需要某种同步,我假设所有可能的用户查询。
答案 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();
}
在编辑时,我注意到了一些方法可以进一步改进这些代码,但我限制自己重构承诺,因为我希望你能够认识到原始中的单一想法变化。