2015-03-01 6 views
1

У меня есть функция, восстанавливающая сообщения в блоге из базы данных. Эта же функция используется для сообщений в блогах определенной категории. Это запрос:Необязательный пошаговый шаг, основанный на параметре запроса

Post.find(params).limit(5) 

Однако когда категория должна быть посмотрел, идентификатор категории должен быть получен первый (запрос-парам является его постоянная ссылка):

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

ответ

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. Если парам существует, чем означает, что мы должны сделать чтобы найти категорию, основанную на параметре, перед тем как сделать запрос Post, в большинстве реализаций обещаний, которые я видел, если вы вернули обещание от .then, тогда обратные вызовы .then, сохраненные в предыдущем обещании, будут выполняться всякий раз, когда возвращаемое значение будет выполнено , (У меня есть en't протестирован с объектом builtIn Promise, но, например, q от KrisKowal способен разрешать любые объекты, подобные обещанию), что имеет место здесь, так как я не знаю о структуре обещаний, которую возвращает Category.findOne({ permalink: categoryParam}), в любом случае, когда запрос чтобы получить категорию, полная стоимость возвращаемого обещания будет равна идентификатору категории
  3. В окончательном then мы должны проверить, существует ли параметр categoryId (он, возможно, был возвращен из предыдущего then), если это так, то обновите params объект с нею
+0

Он использует Bluebird обещания, которые означает, что он использует более быстрый супернабор. –

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 
}); 
Смежные вопросы