基于查询参数的可选承诺步骤

Optional promise-step based on query parameter

本文关键字:承诺 参数 于查询 查询      更新时间:2023-09-26

我有一个从数据库中检索博客文章的函数。同样的功能也用于特定类别的博客文章。这是一个查询:

Post.find( params ).limit(5)

然而,当要查找类别时,必须首先检索该类别的id(查询参数是其永久链接):

Category.findOne({ permalink: req.params.category})

我如何使用承诺来防止必须写这样的重复内容:

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

您可以通过该类别id请求为params做出承诺,也可以在不需要时简单地使用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
});

我提出了这个解决方案,假设您可以访问BuiltInPromise对象

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. 让我们从一个promise开始,它的解析值是请求的category参数
  2. 如果param存在,则意味着我们必须在发出Post请求之前进行查询,以找到基于param的类别。在我所看到的大多数promise实现中,如果您从.then返回promise,则无论何时满足返回值,都将执行存储在前一个promise中的.then回调,(我还没有用内置的in Promise对象进行测试,但例如KrisKowal的q能够解析任何类似Promise的对象)这里的情况就是这样,因为我不知道Category.findOne({ permalink: categoryParam})返回的Promise结构,在任何情况下,当获取类别的查询完成时,返回Promise的实现值将是类别的id
  3. 在最后的then中,我们必须检查categoryId参数是否存在(它可能是从以前的then返回的),如果存在,则用它更新params对象