解析云:在 save() 回调的导出函数中查询不 运行
Parse Cloud: Query not running in exported function from save() callback
我正在使用 Parse 来表示啤酒桶的状态(以及其他)。我想查看存储在 "Notifications" table 中的用户通知,看看他们是否愿意在桶装满时收到通知。
我拥有设置用户通知设置以及在 cloud/notifications.js 中发送通知的所有逻辑。更新小桶的所有逻辑都在 cloud/beer.js 中。我创建了一个名为 "sendKegRefillNotification" 的导出函数,它在通知 table 上执行 query.find() 并从 beer.js.
调用
问题是,当我从 beer.js 调用函数时,它似乎没有执行 query.find(),但是当我从 [=45] 中的作业调用相同的函数时=], 效果很好。
main.js:
require("cloud/beer.js");
require("cloud/notifications.js");
beer.js:
var notify = require("cloud/notifications.js");
var Keg = Parse.Object.extend("Keg");
var fillKeg = function(beerName) {
var promise = new Parse.Promise();
var keg = new Keg();
keg.set("beerName", beerName)
keg.set("kickedReports", []);
keg.save(null, { useMasterKey: true }).then(function(keg) {
console.log("Keg updated to " + beerName + ".");
promise.resolve(keg);
notify.sendKegRefillNotification(keg);
},
function(keg, error) {
promise.reject(error);
});
return promise;
}
Parse.Cloud.define("beerFillKeg", function(request, response) {
var beerName = request.params.name;
if (!beerName) {
response.error("No beer was specified.");
return;
}
if (!util.isUserAdmin(request.user)) {
response.error("User does not have permission to update the keg.");
return;
}
fillKeg(beerName).then(function(keg) {
kegResponse(keg).then(function(result) {
response.success(result);
});
},
function(error) {
response.error(error);
});
});
function kegResponse(keg) {
var promise = new Parse.Promise();
var result = {
id: keg.id,
beer: {
name: keg.get("beerName")
},
filled: keg.createdAt,
kickedReports: []
};
var kickedReports = keg.get("kickedReports");
if (!kickedReports || kickedReports.length == 0) {
promise.resolve(result);
} else {
util.findUsers(kickedReports).then(function(users) {
result.kickedReports = util.infoForUsers(users);
promise.resolve(result);
}, function(users, error) {
console.log(error);
promise.resolve(result);
});
}
return promise;
}
notifications.js:
var Keg = Parse.Object.extend("Keg");
var Notification = Parse.Object.extend("Notifications");
exports.sendKegRefillNotification = function(keg) {
var beerName = keg.get("beerName");
console.log("Sending notifications that keg is refilled to '" + beerName + "'.");
var promise = new Parse.Promise();
var query = new Parse.Query(Notification);
query.include("user");
query.equalTo("keg_filled", true);
query.find({ useMasterKey: true }).then(function(notifications) {
console.log("Found notifications!");
promise.resolve("Found notifications!");
},
function(notifications, error) {
console.error("No notifications");
console.error(error);
promise.reject(error);
});
return promise;
}
Parse.Cloud.job("beerSendRefillNotification", function(request, status) {
var query = new Parse.Query(Keg);
query.descending("createdAt");
query.first().then(function(keg) {
if (!keg) {
status.error("No keg");
return;
}
exports.sendKegRefillNotification(keg);
},
function(keg, error) {
response.error(error);
});
});
当我从 Parse 仪表板 运行 作业 "beerSendRefillNotification" 时,我可以看出 query.find() 正在被调用,因为它打印 "Found notifications!":
E2015-02-23T06:59:49.006Z]v1564 Ran job beerSendRefillNotification with:
Input: {}
Result: success/error was not called
I2015-02-23T06:59:49.055Z]false
I2015-02-23T06:59:49.190Z]Sending notifications that keg is refilled to 'test'.
I2015-02-23T06:59:49.243Z]Found notifications!
但是,当我调用云函数 "beerFillKeg" 时,并不是因为它没有打印 "Found notifications!" 或 "No notifications":
I2015-02-23T07:00:17.414Z]v1564 Ran cloud function beerFillKeg for user HKePOEWZvC with:
Input: {"name":"Duff"}
Result: {"beer":{"name":"Duff"},"filled":{"__type":"Date","iso":"2015-02-23T07:00:17.485Z"},"id":"olLXh0F54E","kickedReports":[]}
I2015-02-23T07:00:17.438Z]false
I2015-02-23T07:00:17.523Z]Keg updated to Duff.
I2015-02-23T07:00:17.525Z]Sending notifications that keg is refilled to 'Duff'.
看起来 Parse 不允许您 运行 从 save() 的回调内部进行查询。当我将 "notify.sendKegRefillNotification(keg);" 移到回调之外时,它起作用了。
var fillKeg = function(beerName) {
var promise = new Parse.Promise();
var keg = new Keg();
keg.set("beerName", beerName)
keg.set("kickedReports", []);
keg.save(null, { useMasterKey: true }).then(function(keg) {
console.log("Keg updated to " + beerName + ".");
console.log("Send notifications.");
promise.resolve(keg);
},
function(keg, error) {
promise.reject(error);
});
notify.sendKegRefillNotification(keg); // Now this works
return promise;
}
任何人都可以进一步说明为什么会这样吗?
终于明白了。在 sendKegRefillNotification
中,您正在调用 query.find({...})
,然后 returning 一个对象。 find
是异步的,您什么都不做等待结果。我认为您需要 return find
函数调用,而不是您在该方法中设置的对象。
换句话说,您已经 运行 了,留下了一些异步 运行 代码。
编辑:我明白你想做什么。这有点道理。您定义了一个承诺,并认为调用者会等待该承诺。问题是,承诺是 defined 在异步块中。在调用者收到它时它还没有任何意义。
我正在使用 Parse 来表示啤酒桶的状态(以及其他)。我想查看存储在 "Notifications" table 中的用户通知,看看他们是否愿意在桶装满时收到通知。
我拥有设置用户通知设置以及在 cloud/notifications.js 中发送通知的所有逻辑。更新小桶的所有逻辑都在 cloud/beer.js 中。我创建了一个名为 "sendKegRefillNotification" 的导出函数,它在通知 table 上执行 query.find() 并从 beer.js.
调用问题是,当我从 beer.js 调用函数时,它似乎没有执行 query.find(),但是当我从 [=45] 中的作业调用相同的函数时=], 效果很好。
main.js:
require("cloud/beer.js");
require("cloud/notifications.js");
beer.js:
var notify = require("cloud/notifications.js");
var Keg = Parse.Object.extend("Keg");
var fillKeg = function(beerName) {
var promise = new Parse.Promise();
var keg = new Keg();
keg.set("beerName", beerName)
keg.set("kickedReports", []);
keg.save(null, { useMasterKey: true }).then(function(keg) {
console.log("Keg updated to " + beerName + ".");
promise.resolve(keg);
notify.sendKegRefillNotification(keg);
},
function(keg, error) {
promise.reject(error);
});
return promise;
}
Parse.Cloud.define("beerFillKeg", function(request, response) {
var beerName = request.params.name;
if (!beerName) {
response.error("No beer was specified.");
return;
}
if (!util.isUserAdmin(request.user)) {
response.error("User does not have permission to update the keg.");
return;
}
fillKeg(beerName).then(function(keg) {
kegResponse(keg).then(function(result) {
response.success(result);
});
},
function(error) {
response.error(error);
});
});
function kegResponse(keg) {
var promise = new Parse.Promise();
var result = {
id: keg.id,
beer: {
name: keg.get("beerName")
},
filled: keg.createdAt,
kickedReports: []
};
var kickedReports = keg.get("kickedReports");
if (!kickedReports || kickedReports.length == 0) {
promise.resolve(result);
} else {
util.findUsers(kickedReports).then(function(users) {
result.kickedReports = util.infoForUsers(users);
promise.resolve(result);
}, function(users, error) {
console.log(error);
promise.resolve(result);
});
}
return promise;
}
notifications.js:
var Keg = Parse.Object.extend("Keg");
var Notification = Parse.Object.extend("Notifications");
exports.sendKegRefillNotification = function(keg) {
var beerName = keg.get("beerName");
console.log("Sending notifications that keg is refilled to '" + beerName + "'.");
var promise = new Parse.Promise();
var query = new Parse.Query(Notification);
query.include("user");
query.equalTo("keg_filled", true);
query.find({ useMasterKey: true }).then(function(notifications) {
console.log("Found notifications!");
promise.resolve("Found notifications!");
},
function(notifications, error) {
console.error("No notifications");
console.error(error);
promise.reject(error);
});
return promise;
}
Parse.Cloud.job("beerSendRefillNotification", function(request, status) {
var query = new Parse.Query(Keg);
query.descending("createdAt");
query.first().then(function(keg) {
if (!keg) {
status.error("No keg");
return;
}
exports.sendKegRefillNotification(keg);
},
function(keg, error) {
response.error(error);
});
});
当我从 Parse 仪表板 运行 作业 "beerSendRefillNotification" 时,我可以看出 query.find() 正在被调用,因为它打印 "Found notifications!":
E2015-02-23T06:59:49.006Z]v1564 Ran job beerSendRefillNotification with:
Input: {}
Result: success/error was not called
I2015-02-23T06:59:49.055Z]false
I2015-02-23T06:59:49.190Z]Sending notifications that keg is refilled to 'test'.
I2015-02-23T06:59:49.243Z]Found notifications!
但是,当我调用云函数 "beerFillKeg" 时,并不是因为它没有打印 "Found notifications!" 或 "No notifications":
I2015-02-23T07:00:17.414Z]v1564 Ran cloud function beerFillKeg for user HKePOEWZvC with:
Input: {"name":"Duff"}
Result: {"beer":{"name":"Duff"},"filled":{"__type":"Date","iso":"2015-02-23T07:00:17.485Z"},"id":"olLXh0F54E","kickedReports":[]}
I2015-02-23T07:00:17.438Z]false
I2015-02-23T07:00:17.523Z]Keg updated to Duff.
I2015-02-23T07:00:17.525Z]Sending notifications that keg is refilled to 'Duff'.
看起来 Parse 不允许您 运行 从 save() 的回调内部进行查询。当我将 "notify.sendKegRefillNotification(keg);" 移到回调之外时,它起作用了。
var fillKeg = function(beerName) {
var promise = new Parse.Promise();
var keg = new Keg();
keg.set("beerName", beerName)
keg.set("kickedReports", []);
keg.save(null, { useMasterKey: true }).then(function(keg) {
console.log("Keg updated to " + beerName + ".");
console.log("Send notifications.");
promise.resolve(keg);
},
function(keg, error) {
promise.reject(error);
});
notify.sendKegRefillNotification(keg); // Now this works
return promise;
}
任何人都可以进一步说明为什么会这样吗?
终于明白了。在 sendKegRefillNotification
中,您正在调用 query.find({...})
,然后 returning 一个对象。 find
是异步的,您什么都不做等待结果。我认为您需要 return find
函数调用,而不是您在该方法中设置的对象。
换句话说,您已经 运行 了,留下了一些异步 运行 代码。
编辑:我明白你想做什么。这有点道理。您定义了一个承诺,并认为调用者会等待该承诺。问题是,承诺是 defined 在异步块中。在调用者收到它时它还没有任何意义。