从云代码函数返回基于 objectId 的 Parse.User 对象列表
Posted
技术标签:
【中文标题】从云代码函数返回基于 objectId 的 Parse.User 对象列表【英文标题】:Returning list of Parse.User objects based on objectId from Cloud Code Function 【发布时间】:2015-08-18 15:00:06 【问题描述】:这是我的云代码功能:
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 可供查询时,简单地阻止并等待对象填充是行不通的。
我需要对所有可能的用户查询进行某种同步。
【问题讨论】:
您已将问题标记为 promise,那么您是否尝试过使用它们? @Wain 您能否提供一个示例代码,说明如何为这个用例提供 Promise? 请出示function nearby()
的出处。需要看看它是否返回一个承诺。另外,请在nearby
中描述正在查询的数据。列名和类型(重要:该表中是否有指向 _User 的指针?)
@danh 这里是部署在云代码gist.github.com/maximveksler/59f95a4a66232df51eed 中的当前版本的实际复制和粘贴。附近表的结构可能会发生变化,将源和附近作为引用而不是指针将有助于解决问题吗?
【参考方案1】:
好消息是您的NearBy
模型包含指向用户表的指针。该指针的结尾可以通过include
-ing 在NearBy
查询中急切获取...
function queryNearby(userId, sourceColumn, nearColumn, callback)
var query = new Parse.Query(NearBy);
query.include("near");
// ...
还有一些不那么令人高兴的消息,但并非立即不高兴:如果需要另一个查询(或另一个异步操作),那么在 2-3 级回调间接构建它时会很头疼。你关于承诺的想法是正确的。考虑重构您的函数以始终返回 Promise 并使用从其 SDK 返回的 parse 的 Promise。
编辑为了详细说明 Promise 的使用,这里有一个修改为使用 Promise 的代码示例。
我们的想法是,我们拥有创建和返回 Promise 的函数,而不是传递回调函数和嵌套调用 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();
在编辑时,我注意到了一些进一步改进此代码的方法,但我将自己限制在为 promise 进行重构,因为我希望您认识到原始代码中的单一想法变化。
【讨论】:
您能否提供一个实现承诺的自定义函数的示例?我并不是说像 parse 文档这样的东西提供了他们通过回调设置超时的地方,而是一些执行计算逻辑的东西。我返回一个承诺,然后去做一些工作,然后解决这个承诺。重写我自己的代码,或者参考其他人的代码来显示这一点也很棒。 tnx. @MaximVeksler - 我尝试在您的代码中说明这个想法。我建议将其与原件并列进行审查。还可以查看 parse 的 promise 指南 (parse.com/docs/js/guide#promises)。一旦你掌握了这个窍门,你就再也不想写(或读)传统的回调代码了。 感谢@danh 我确实阅读了所有关于 Promises 的 parse 文档,并且我知道 find() 返回一个 Promise,它可以用作返回值。我的问题是用一个承诺重新实现 queryNearby:如果我可以从 queryNearby 返回一个承诺 并 完成工作,然后执行 Promise.resolved() 那么一切都会变得更简单。感谢您编辑我的代码,但我认为您错过了对 queryNearByNearId() 的第二次调用,这对我的逻辑至关重要,而且我相信演示代码旨在显示使用 include() 获取 Parse.User 对象? @MaximVeksler,github 代码显示了对 queryNearByNearId 的单个调用。我没有看到第二个电话。我如此参与您的代码,我忘记了我的答案的要点是包含()!现在将对其进行编辑。回顾一下:这里的问题是如何检索指向的用户,而答案——我认为是正确的——是使用 include()。我顺便提到过,promise 是一种更好的组织代码的方式,并且花了一些时间将你的代码重构为一个 Promise 教程。我认为它是正确的(或接近),但重点是:使用承诺。以上是关于从云代码函数返回基于 objectId 的 Parse.User 对象列表的主要内容,如果未能解决你的问题,请参考以下文章