如何使用 Promises 有条件地执行第二个任务?
How do I conditionally perform a second task using Promises?
我正在使用 Bookshelf.js,一个基于 Promise 的 ORM 模块,来执行几个数据库查找。给定用户提供的密钥,我需要确定该密钥是否与两个 table 之一中的记录匹配。如果我在第一个 table 中找到它,我需要 return 那个记录。但是,如果我在第一个 table 中找不到它,我需要在第二个 table 中查找。基本上,我需要有条件地执行一个 then
块。我如何使用承诺来完成这个?这是我目前拥有的,非常混乱,事实上,我有点不清楚如果我在第一个 School
查找中调用 resolve
会发生什么——第二个 then
块也执行?
exports.findTargetRecord = function(code){
return new Promise(function(resolve, reject){
Schools
.query({ where: { code: code }})
.fetchOne()
.then(school => {
if(school) return resolve(school);
return Organizations
.query({ where: { code: code }})
.fetchOne();
})
.then(org => {
if(org) return resolve(org);
resolve(null);
})
.catch(err => reject(err));
});
};
有没有更简洁的写法?
您可以将整个 else
逻辑保留在 then
块中:
exports.findTargetRecord = function(code){
return new Promise(function(resolve, reject){
Schools
.query({ where: { code: code }})
.fetchOne()
.then(school => {
if(school) return resolve(school);
return Organizations
.query({ where: { code: code }})
.fetchOne()
.then(org => {
if(org) return resolve(org);
resolve(null);
})
})
.catch(err => reject(err));
});
};
此外,您的代码可以像这样重写(较短的版本):
exports.findTargetRecord = function(code){
return Schools
.query({ where: { code: code }})
.fetchOne()
.then(school => {
if(school) return school;
return Organizations
.query({ where: { code: code }})
.fetchOne();
})
.catch(err => reject(err));
使用 promises 作为代理和常规 if
:
exports.findTargetRecord = function(code){
const school = Schools.query({ where: { code: code }}).fetchOne();
school = school.then(school =>
school || Organizations.query({ where: { code: code }}).fetchOne())
return school;
}
或者使用 bluebird 支持的协程(bluebird 附带书架):
exports.findTargetRecord = Promise.coroutine(function*(code) {
var school = yield Schools.query({ where: { code: code }}).fetchOne();
if(school) return school;
return Organizations.query({ where: { code: code }}).fetchOne();
});
我正在使用 Bookshelf.js,一个基于 Promise 的 ORM 模块,来执行几个数据库查找。给定用户提供的密钥,我需要确定该密钥是否与两个 table 之一中的记录匹配。如果我在第一个 table 中找到它,我需要 return 那个记录。但是,如果我在第一个 table 中找不到它,我需要在第二个 table 中查找。基本上,我需要有条件地执行一个 then
块。我如何使用承诺来完成这个?这是我目前拥有的,非常混乱,事实上,我有点不清楚如果我在第一个 School
查找中调用 resolve
会发生什么——第二个 then
块也执行?
exports.findTargetRecord = function(code){
return new Promise(function(resolve, reject){
Schools
.query({ where: { code: code }})
.fetchOne()
.then(school => {
if(school) return resolve(school);
return Organizations
.query({ where: { code: code }})
.fetchOne();
})
.then(org => {
if(org) return resolve(org);
resolve(null);
})
.catch(err => reject(err));
});
};
有没有更简洁的写法?
您可以将整个 else
逻辑保留在 then
块中:
exports.findTargetRecord = function(code){
return new Promise(function(resolve, reject){
Schools
.query({ where: { code: code }})
.fetchOne()
.then(school => {
if(school) return resolve(school);
return Organizations
.query({ where: { code: code }})
.fetchOne()
.then(org => {
if(org) return resolve(org);
resolve(null);
})
})
.catch(err => reject(err));
});
};
此外,您的代码可以像这样重写(较短的版本):
exports.findTargetRecord = function(code){
return Schools
.query({ where: { code: code }})
.fetchOne()
.then(school => {
if(school) return school;
return Organizations
.query({ where: { code: code }})
.fetchOne();
})
.catch(err => reject(err));
使用 promises 作为代理和常规 if
:
exports.findTargetRecord = function(code){
const school = Schools.query({ where: { code: code }}).fetchOne();
school = school.then(school =>
school || Organizations.query({ where: { code: code }}).fetchOne())
return school;
}
或者使用 bluebird 支持的协程(bluebird 附带书架):
exports.findTargetRecord = Promise.coroutine(function*(code) {
var school = yield Schools.query({ where: { code: code }}).fetchOne();
if(school) return school;
return Organizations.query({ where: { code: code }}).fetchOne();
});