可选的promise-step基于查询参数

时间:2015-03-01 01:24:26

标签: javascript mongoose promise bluebird

我有一个从数据库中检索博客帖子的功能。相同的功能用于特定类别的博客帖子。这是查询:

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
  })
}

2 个答案:

答案 0 :(得分:3)

您可以对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
});

答案 1 :(得分:1)

我假设您有权访问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
        })
  })

让我解释一下上面的解决方案:

  1. 让我们以一个承诺,其决议价值是请求的category参数
  2. 如果存在param而不是意味着我们必须在发出Post请求之前根据param查询类别,在大多数承诺的实现中我都会看到你是否返回了一个承诺从.then开始,只要满足返回值,就会执行前一个promise中存储的.then回调,(我还没有使用builtIn Promise对象进行测试,例如{{1}来自KrisKowal的能够解决任何类似承诺的对象),因为我不知道q返回的promise结构,在任何情况下,当获得类别的查询完成时返回承诺的实现价值将是类别ID
  3. 在最后的Category.findOne({ permalink: categoryParam})中,我们必须检查then param是否存在(可能是从之前的categoryId返回),如果是,则更新then用它来对象