基于查询参数的可选承诺步骤
Optional promise-step based on query parameter
我有一个从数据库中检索博客文章的函数。相同的功能用于特定类别的博客文章。这是查询:
Post.find( params ).limit(5)
然而,当要查找一个类别时,必须首先检索类别的 id(查询参数是它的永久链接):
Category.findOne({ permalink: req.params.category})
我如何使用 promises 来避免像这样写重复的东西:
// a category is present
if (typeof req.params.category !== 'undefined'){
Category.findOne({ permalink: req.params.category}).then(function(category){
params.category = category.id
Post.find(params).limit(5).exec(function(err,posts){
// yada-yada
})
}
}
// no category
else {
Post.find(params).limit(5).exec(function(err,posts){
// yada-yada
})
}
假设您可以访问 BuiltIn Promise Object
,我想出了这个解决方案
Promise.resolve(req.params.category)
.then(function (categoryParam) {
if (categoryParam) {
// if you return a promise then the `then` function stored in the
// previous promise will be executed when this promise (the one returned
// here) is resolved
return Category
.findOne({ permalink: categoryParam})
.then(function (category) {
return category.id;
});
} else {
// nothing to do here so the resolution value of this promise is undefined
}
})
.then(function (categoryId) {
if (categoryId) {
// checks the existance of the categoryId
params.category = categoryId;
}
Post
.find(params)
.limit(5)
.exec(function(err,posts){
// yada-yada
})
})
让我解释一下上面的解决方案:
- 让我们从一个承诺开始,它的解析值为请求的
category
参数
- 如果参数存在,则意味着我们必须在发出
Post
请求之前根据参数进行查询以查找类别,在我见过的大多数承诺实现中,如果您 return 来自 .then
的承诺,然后存储在前一个承诺中的 .then
回调将在满足 returning 值时执行,(我没有使用内置 Promise 对象进行测试但是例如来自 KrisKowal 的 q
能够解析任何类似 promise 的对象)这里就是这种情况,因为我不知道 Category.findOne({ permalink: categoryParam})
returns 的 promise 结构,在任何情况下当获取类别的查询完成时,returning 承诺的实现值将是类别的 id
- 在最后的
then
中,我们必须检查 categoryId
参数是否存在(它可能已从之前的 then
中 return 编辑),如果存在则用它更新 params
对象
您可以为 params
做出承诺 - 来自该类别 ID 请求,或者在不需要时简单地使用 Promise.resolve
。然后,您可以简单地链接您的 find
调用:
((typeof req.params.category !== 'undefined')
? Category.findOne({permalink: req.params.category}).then(function(category){
params.category = category.id
return params;
})
: Promise.resolve(params)
).then(function(p) {
return Post.find(p).limit(5).exec();
}).then(function(posts) {
// yada-yada
});
我有一个从数据库中检索博客文章的函数。相同的功能用于特定类别的博客文章。这是查询:
Post.find( params ).limit(5)
然而,当要查找一个类别时,必须首先检索类别的 id(查询参数是它的永久链接):
Category.findOne({ permalink: req.params.category})
我如何使用 promises 来避免像这样写重复的东西:
// a category is present
if (typeof req.params.category !== 'undefined'){
Category.findOne({ permalink: req.params.category}).then(function(category){
params.category = category.id
Post.find(params).limit(5).exec(function(err,posts){
// yada-yada
})
}
}
// no category
else {
Post.find(params).limit(5).exec(function(err,posts){
// yada-yada
})
}
假设您可以访问 BuiltIn Promise Object
,我想出了这个解决方案Promise.resolve(req.params.category)
.then(function (categoryParam) {
if (categoryParam) {
// if you return a promise then the `then` function stored in the
// previous promise will be executed when this promise (the one returned
// here) is resolved
return Category
.findOne({ permalink: categoryParam})
.then(function (category) {
return category.id;
});
} else {
// nothing to do here so the resolution value of this promise is undefined
}
})
.then(function (categoryId) {
if (categoryId) {
// checks the existance of the categoryId
params.category = categoryId;
}
Post
.find(params)
.limit(5)
.exec(function(err,posts){
// yada-yada
})
})
让我解释一下上面的解决方案:
- 让我们从一个承诺开始,它的解析值为请求的
category
参数 - 如果参数存在,则意味着我们必须在发出
Post
请求之前根据参数进行查询以查找类别,在我见过的大多数承诺实现中,如果您 return 来自.then
的承诺,然后存储在前一个承诺中的.then
回调将在满足 returning 值时执行,(我没有使用内置 Promise 对象进行测试但是例如来自 KrisKowal 的q
能够解析任何类似 promise 的对象)这里就是这种情况,因为我不知道Category.findOne({ permalink: categoryParam})
returns 的 promise 结构,在任何情况下当获取类别的查询完成时,returning 承诺的实现值将是类别的 id - 在最后的
then
中,我们必须检查categoryId
参数是否存在(它可能已从之前的then
中 return 编辑),如果存在则用它更新params
对象
您可以为 params
做出承诺 - 来自该类别 ID 请求,或者在不需要时简单地使用 Promise.resolve
。然后,您可以简单地链接您的 find
调用:
((typeof req.params.category !== 'undefined')
? Category.findOne({permalink: req.params.category}).then(function(category){
params.category = category.id
return params;
})
: Promise.resolve(params)
).then(function(p) {
return Post.find(p).limit(5).exec();
}).then(function(posts) {
// yada-yada
});