使用 Promises 清理意大利面条代码
Cleaning up Spaghetti Code w/ Promises
在我的一个 beforeSave 函数中,我需要在响应成功或错误之前检查一些条件。
问题是,我的代码看起来真的很乱,有时 success/error 没有被调用:
Parse.Cloud.beforeSave("Entry", function(request, response) {
var entry = request.object;
var contest = request.object.get("contest");
entry.get("user").fetch().then(function(fetchedUser) {
contest.fetch().then(function(fetchedContest) {
if ( fetchedUser.get("fundsAvailable") < fetchedContest.get("entryFee") ) {
response.error('Insufficient Funds.');
} else {
fetchedContest.get("timeSlot").fetch().then(function(fetchedTimeSlot) {
var now = new Date();
if (fetchedTimeSlot.get("startDate") < now) {
response.error('This contest has already started.');
} else {
contest.increment("entriesCount");
contest.increment("entriesLimit", 0); //have to do this, otherwise entriesLimit is undefined in save callback (?)
contest.save().then(function(fetchedContest) {
if (contest.get("entriesCount") > contest.get("entriesLimit")) {
response.error('The contest is full.');
} else {
response.success();
}
});
}
});
}
});
});
});
我一直在尝试学习 promises 来整理它,这是我的(失败的)尝试:
Parse.Cloud.beforeSave("Entry", function(request, response) {
var entry = request.object;
var contest = request.object.get("contest");
entry.get("user").fetch().then(function(fetchedUser) {
contest.fetch().then(function(fetchedContest) {
if ( fetchedUser.get("fundsAvailable") < fetchedContest.get("entryFee") ) {
response.error('Insufficient Funds.');
}
return fetchedContest;
});
}).then(function(result) {
result.get("timeSlot").fetch().then(function(fetchedTimeSlot) {
var now = new Date();
if (fetchedTimeSlot.get("startDate") < now) {
response.error('This contest has already started.');
}
});
}).then(function() {
contest.increment("entriesCount");
contest.increment("entriesLimit", 0);
contest.save().then(function(fetchedContest) {
if (contest.get("entriesCount") > contest.get("entriesLimit")) {
response.error('The contest is full.');
}
});
}).then(function() {
response.success();
}, function(error) {
response.error(error);
});
});
任何关于如何为此使用承诺的帮助或示例将不胜感激。显然我还没有完全理解它们在语法上是如何工作的。
你正在犯菜鸟错误,即在链接它们时不返回 .then
内的承诺,除此之外,即使你调用 response.error(..
,你的链仍然会继续,打破链的最简单方法是抛出错误,您的代码可以展平为:
Parse.Cloud.beforeSave("Entry", (request, response) => {
var entry = request.object,
, contest = request.object.get("contest")
, fetchedUser
, fetchedContest;
entry.get("user").fetch()
.then(_fetchedUser => {
fetchedUser = _fetchedUser;
return contest.fetch();
}).then(_fetchedContest => {
fetchedContest = _fetchedContest;
if ( fetchedUser.get("fundsAvailable") < fetchedContest.get("entryFee") )
return Promise.reject('Insufficient Funds.');
return fetchedContest.get("timeSlot").fetch();
}).then(fetchedTimeSlot => {
var now = new Date();
if (fetchedTimeSlot.get("startDate") < now)
return Promise.reject('This contest has already started.');
contest.increment("entriesCount");
contest.increment("entriesLimit", 0); //have to do this, otherwise entriesLimit is undefined in save callback (?)
return contest.save();
}).then(fetchedContest => {
if (contest.get("entriesCount") > contest.get("entriesLimit"))
return Promise.reject('The contest is full.');
response.success();
}).catch(response.error.bind(response));
});
我通过使用承诺链首先组装获取的变量来稍微清理一下。这遵循了一些样式规则,使其更具可读性(无论如何对我来说)...
Parse.Cloud.beforeSave("Entry", function(request, response) {
var entry = request.object;
var contest = request.object.get("contest");
var fetchedUser, fetchedContest;
var errorMessage;
entry.get("user").fetch().then(function(result) {
fetchedUser = result;
return contest.fetch();
}).then(function(result) {
fetchedContest = result;
return fetchedContest.get("timeSlot").fetch();
}).then(function(fetchedTimeSlot) {
// now we have all the variables we need to determine validity
var now = new Date();
var hasSufficientFunds = fetchedUser.get("fundsAvailable") >= fetchedContest.get("entryFee");
var contestNotStarted = fetchedTimeSlot.get("startDate") >= now;
if (hasSufficientFunds && contestNotStarted) {
contest.increment("entriesCount");
contest.increment("entriesLimit", 0); //have to do this, otherwise entriesLimit is undefined in save callback (?)
return contest.save();
} else {
errorMessage = (hasSufficientFunds)? 'This contest has already started.' : 'Insufficient Funds.';
return null;
}
}).then(function(result) {
if (!result) {
response.error(errorMessage);
} else {
if (contest.get("entriesCount") > contest.get("entriesLimit")) {
response.error('The contest is full.');
} else {
response.success();
}
}
}, function(error) {
response.error(error);
});
});
请注意我们如何从不让 response.anything() 悬而未决,我们总是通过 return.
明确什么流向下一个承诺。
在我的一个 beforeSave 函数中,我需要在响应成功或错误之前检查一些条件。
问题是,我的代码看起来真的很乱,有时 success/error 没有被调用:
Parse.Cloud.beforeSave("Entry", function(request, response) {
var entry = request.object;
var contest = request.object.get("contest");
entry.get("user").fetch().then(function(fetchedUser) {
contest.fetch().then(function(fetchedContest) {
if ( fetchedUser.get("fundsAvailable") < fetchedContest.get("entryFee") ) {
response.error('Insufficient Funds.');
} else {
fetchedContest.get("timeSlot").fetch().then(function(fetchedTimeSlot) {
var now = new Date();
if (fetchedTimeSlot.get("startDate") < now) {
response.error('This contest has already started.');
} else {
contest.increment("entriesCount");
contest.increment("entriesLimit", 0); //have to do this, otherwise entriesLimit is undefined in save callback (?)
contest.save().then(function(fetchedContest) {
if (contest.get("entriesCount") > contest.get("entriesLimit")) {
response.error('The contest is full.');
} else {
response.success();
}
});
}
});
}
});
});
});
我一直在尝试学习 promises 来整理它,这是我的(失败的)尝试:
Parse.Cloud.beforeSave("Entry", function(request, response) {
var entry = request.object;
var contest = request.object.get("contest");
entry.get("user").fetch().then(function(fetchedUser) {
contest.fetch().then(function(fetchedContest) {
if ( fetchedUser.get("fundsAvailable") < fetchedContest.get("entryFee") ) {
response.error('Insufficient Funds.');
}
return fetchedContest;
});
}).then(function(result) {
result.get("timeSlot").fetch().then(function(fetchedTimeSlot) {
var now = new Date();
if (fetchedTimeSlot.get("startDate") < now) {
response.error('This contest has already started.');
}
});
}).then(function() {
contest.increment("entriesCount");
contest.increment("entriesLimit", 0);
contest.save().then(function(fetchedContest) {
if (contest.get("entriesCount") > contest.get("entriesLimit")) {
response.error('The contest is full.');
}
});
}).then(function() {
response.success();
}, function(error) {
response.error(error);
});
});
任何关于如何为此使用承诺的帮助或示例将不胜感激。显然我还没有完全理解它们在语法上是如何工作的。
你正在犯菜鸟错误,即在链接它们时不返回 .then
内的承诺,除此之外,即使你调用 response.error(..
,你的链仍然会继续,打破链的最简单方法是抛出错误,您的代码可以展平为:
Parse.Cloud.beforeSave("Entry", (request, response) => {
var entry = request.object,
, contest = request.object.get("contest")
, fetchedUser
, fetchedContest;
entry.get("user").fetch()
.then(_fetchedUser => {
fetchedUser = _fetchedUser;
return contest.fetch();
}).then(_fetchedContest => {
fetchedContest = _fetchedContest;
if ( fetchedUser.get("fundsAvailable") < fetchedContest.get("entryFee") )
return Promise.reject('Insufficient Funds.');
return fetchedContest.get("timeSlot").fetch();
}).then(fetchedTimeSlot => {
var now = new Date();
if (fetchedTimeSlot.get("startDate") < now)
return Promise.reject('This contest has already started.');
contest.increment("entriesCount");
contest.increment("entriesLimit", 0); //have to do this, otherwise entriesLimit is undefined in save callback (?)
return contest.save();
}).then(fetchedContest => {
if (contest.get("entriesCount") > contest.get("entriesLimit"))
return Promise.reject('The contest is full.');
response.success();
}).catch(response.error.bind(response));
});
我通过使用承诺链首先组装获取的变量来稍微清理一下。这遵循了一些样式规则,使其更具可读性(无论如何对我来说)...
Parse.Cloud.beforeSave("Entry", function(request, response) {
var entry = request.object;
var contest = request.object.get("contest");
var fetchedUser, fetchedContest;
var errorMessage;
entry.get("user").fetch().then(function(result) {
fetchedUser = result;
return contest.fetch();
}).then(function(result) {
fetchedContest = result;
return fetchedContest.get("timeSlot").fetch();
}).then(function(fetchedTimeSlot) {
// now we have all the variables we need to determine validity
var now = new Date();
var hasSufficientFunds = fetchedUser.get("fundsAvailable") >= fetchedContest.get("entryFee");
var contestNotStarted = fetchedTimeSlot.get("startDate") >= now;
if (hasSufficientFunds && contestNotStarted) {
contest.increment("entriesCount");
contest.increment("entriesLimit", 0); //have to do this, otherwise entriesLimit is undefined in save callback (?)
return contest.save();
} else {
errorMessage = (hasSufficientFunds)? 'This contest has already started.' : 'Insufficient Funds.';
return null;
}
}).then(function(result) {
if (!result) {
response.error(errorMessage);
} else {
if (contest.get("entriesCount") > contest.get("entriesLimit")) {
response.error('The contest is full.');
} else {
response.success();
}
}
}, function(error) {
response.error(error);
});
});
请注意我们如何从不让 response.anything() 悬而未决,我们总是通过 return.
明确什么流向下一个承诺。