【问题标题】:Optional promise-step based on query parameter基于查询参数的可选承诺步骤
【发布时间】:2015-05-01 13:54:51
【问题描述】:

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

Post.find( params ).limit(5)

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

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

我如何使用 Promise 来避免重复写这样的东西:

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

【问题讨论】:

    标签: javascript mongoose promise bluebird


    【解决方案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. 让我们从一个 promise 开始,它的分辨率值是请求的 category 参数
    2. 如果参数存在,则意味着我们必须在发出 Post 请求之前根据参数进行查询以查找类别,在大多数承诺的实现中,如果您从 @987654325 返回承诺,我会看到@ 然后存储在前一个 promise 中的 .then 回调将在返回值完成时执行,(我没有使用内置的 Promise 对象进行测试,但例如来自 KrisKowal 的 q 能够解析任何类似 promise 的对象) 这是这种情况,因为我不知道Category.findOne({ permalink: categoryParam}) 返回的承诺结构,在任何情况下,当获取类别的查询完成时,返回承诺的履行值将是类别的 id
    3. 在最后的then 中,我们必须检查categoryId 参数是否存在(它可能已从之前的then 返回),如果存在,则使用它更新params 对象

    【讨论】:

    • 他使用的是 bluebird promise,这意味着他使用的是更快的超集。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2016-10-25
      • 2017-05-22
      • 1970-01-01
      • 2016-12-16
      • 2018-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-02
      相关资源
      最近更新 更多