2016-03-17 4 views
2

Например,Как вернуть ответ клиенту посреди обещания?

Comments.findOne({user: req.user.id}).exce() 
.then(function(comment) { 
    if(comment) { 
    // how to make this return immediately and break the rest then? 
    return res.json({error: 'Already commented'}); 
    } else { 
    return Posts.findOne({postId: req.params.id}).exec(); 
    } 
}) 
.then(function(post) { 
    if(post) { 
    var comment = new Comment({user: req.user.id, data: req.body.comment}) 
    return {post: post, comment: comment.save()}; 
    } else { 
    return res.json({error: 'Post not exist'}); 
    } 
}) 
.then(function(data) { 
    post.comments.push(comment._id); 
    return post.save(); 
}); 
.then(function(post) { 
    return res.json({ok: 1}) 
}) 
.catch(function(e)) { 
    return res.json(error: e); 
}); 

Пишется право это обещание? Как написать такое обещание? Callbacks/Promises - головная боль ...

+1

Возможный дубликат [как разорвать цепь обещание] (http://stackoverflow.com/questions/28803287/how-to-break-prom-chain) – mido

+0

Что означает «вернуть ответ клиенту в середине обещания»? Что именно вы пытаетесь достичь? – jfriend00

+0

FYI, есть посторонний ';' перед последним '.then()' в вашем коде, который вызовет ошибку. Это произойдет не так, как если бы вы закодировали как '}). Then()' вместо того, чтобы поместить '.then()' на следующую строку. – jfriend00

ответ

1

Вам просто нужно throw или вернуть отбраковки обещание вызвать обработку ошибки в обещаниях, как показано в этом примере:

Comments.findOne({user: req.user.id}).exce() 
.then(function(comment) { 
    if(comment) { 
    // to bypass all the other .then() resolve handlers, either 
    // throw an error here or return a rejected promise 
    throw new Error(res.json({error: 'Already commented'})); 
    } else { 
    return Posts.findOne({postId: req.params.id}).exec(); 
    } 
}) 

Обещания «кинуть безопасно», что означает, что .then() поймает любое исключение и превратит его в отвергнутое обещание. Это приведет к обходу любого последующего .then() обработчиков разрешений и вместо этого перейдет к следующему reject обработчику или .catch() обработчику.


FYI, вы должны быть осторожны в вашем коде, потому что, когда вы .catch(), а затем просто вернуться из этого, он изменяет свое состояние обещания от отвергнуто до решена, и он будет выглядеть как успешное обещание, когда вы на самом деле имели ошибка, и любой вызывающий может подумать, что все прошло успешно. Это связано с тем, что инфраструктура обещаний предполагает, что если вы ответите на ошибку и вернете значение, которое вы «обработали» ошибку, и состояние теперь успешно разрешено. Чтобы разрешить ошибку продолжать распространяться на более высокие звонящих из .catch(), вы должны повторно бросить или вернуть отклоненный обещание:

blah(...).then(...) 
.catch(function(e)) { 
    throw new Error(res.json(error: e)); 
}); 
3

Вы используете синюю птицу, она поддерживает cancellation. Вот пример:

var Promise = require('bluebird'); 
// enable cancellation 
Promise.config({ 
    cancellation: true 
}); 

// store your promise chain 
var myPromise = Promise.resolve().then(() => { 
    return 'foo'; 
}).then((res) => { 
    console.log(res); 
    // call cancel on the chain when needed 
    myPromise.cancel(); 
    return res; 
}).then((res) => { 
    // this will not be executed 
    console.log(res + '2'); 
}); 
+0

ОП не пытается отменить обещание. Они пытаются разбить цепочку .then(), которая обычно выполняется путем простого отклонения (либо бросания, либо возврата отклоненного обещания). Вот как вы прервите цепочку обещаний и вместо этого выполните обработку ошибок. – jfriend00

Смежные вопросы