我正在开发一个在线商店应用程序,并使用Parse作为后端。我商店中每件商品的数量有限。以下是我processOrder
函数执行操作的高级描述:
理想情况下,上述步骤应该专门执行。我了解到Javascript是一个单线程和基于事件的,所以这是我的问题:
以下是我的代码:
Parse.Cloud.define("processOrder", function(request, response) {
Parse.Cloud.useMasterKey();
var orderDetails = {'apple':2, 'pear':3};
var query = new Parse.Query("Product");
query.containedIn("name", ['apple', 'pear']);
query.find().then(function(results) {
// check if any dish is out of stock or not
_.each(results, function(item) {
var remaining = item.get("remaining");
var required = orderDetails[item.get("name")];
if (remaining < required)
return Parse.Promise.error(name + " is out of stock");
});
return results;
}).then(function(results) {
// make sure the remaining count does not become negative
var promises = [];
_.each(results, function(item) {
item.increment("remaining", -orderDetails[item.get("name")]);
var single_promise = item.save().then(function(savedItem) {
if (savedItem.get("remaining") < 0) {
savedItem.increment("remaining", orderDetails[savedItem.get("name")]);
return savedItem.save().then(function(revertedItem) {
return Parse.Promise.error(savedItem.get("name") + " is out of stock");
}, function(error){
return Parse.Promise.error("Failed to revert order");
});
}
}, function(error) {
return Parse.Promise.error("Failed to update database");
});
promises.push(single_promise);
});
return Parse.Promise.when(promises);
}).then(function() {
// order placed successfully
response.success();
}, function(error) {
response.error(error);
});
});
答案 0 :(得分:0)
在Javascript中无法将上述步骤放在关键部分,对吗?
看,这是令人惊讶的部分。在JavaScript 中,所有内容都在关键部分中运行。没有先发制人和多处理是合作的。如果您的代码开始运行,那么在您的代码完成之前,其他任何代码都无法运行。
即使您的代码已完成执行。
问题是,你正在做IO,而JavaScript中的IO会在实际发生类似阻塞代码之前产生回事件循环。因此,当您创建并运行查询时,您实际上并不会立即继续运行(这就是您的回调/承诺代码的内容)。
理想情况下,上述步骤应该专门执行。
可悲的是,这不是一个JavaScript问题,在这种情况下,这是一个主机环境问题Parse。这是因为当你使用他们的API(通过回调和承诺)时,你必须明确地控制其他代码,并由他们来解决它。
幸运的是,parse has atomic counters。来自API文档:
为了帮助存储计数器类型数据,Parse提供了以原子方式递增(或递减)任何数字字段的方法。因此,相同的更新可以重写为。
gameScore.increment("score");
gameScore.save();
您还可以使用原子数组操作。由于您可以原子地执行步骤3,因此可以保证计数器代表实际库存。