2015-10-04 97 views
3

我有諾言鏈,看起來像這樣:如何(優雅)中斷承諾鏈執行符合Q

module.exports.deleteCommunityFollower = function deleteCommunityFollower(req, res){ 
    var communityId = req.params.userId; 
    var followerId = req.session.passport.user.userId; 

    var community = new user_model.User(communityId); 
    community.getFollower(followerId) 
    .then(function(data) { 
     if(data.length === 0) { 
     res.sendStatus(404); //no follower found, interrupt execution 
     } else { 
     return community.removeFollower(data[0]); //returns a promise 
     }  
    }) 
    .then(function() { 
     res.sendStatus(201); //follower removed, success 
    }) 
    .fail(function(error) { 
     errorHelper.diagnosticsUploader(error, community); 
     res.sendStatus(500);  
    }); 
} 

我在這裏的問題是關於線res.sendStatus(404)。這是一種中斷承諾鏈執行的正確和優雅的方式嗎?背景是,有時當鏈接承諾時,我發現類似這樣的情況,您需要停止執行鏈的原因是不是錯誤。我知道我可以在data.length === 0上拋出一個人爲錯誤,但這對我來說看起來很不雅觀。

在上面的代碼中,當data.length === 0爲真時,我只是返回一個http響應,並且不會將任何值返回給promise解析器,從而有效地阻止鏈執行繼續。不過,我想驗證這是否是推薦的做法。留下一個承諾掛中途在我看來就像它可以是一個麻煩,今後源(?內存泄漏)

+0

您是否使用本地承諾? – thefourtheye

+0

@thefourtheye我正在使用Q庫(kriskowal) –

+0

@LuisDelgado您運行的是哪個版本的Node? –

回答

2

由於您使用現代化節點,這裏是我將如何使用Q.async寫:

const deleteFollower = Q.async(function*(communityId, followerId){ 
    const community = new user_model.User(communityId); 
    let followers = yield community.getFollower(followerId); 
    if(followers.length) === 0; return false; 
    yield community.removeFollower(follower[0]); 
    return true; 
}); 

讀取像一個同步功能,完全平坦,好吧?

我省略了從req/res中提取內容的代碼,因爲這會使代碼更難以測試,而且它應該可以分開。我這樣稱呼它:

function handler(req, res){ 
    var communityId = req.params.userId; 
    var followerId = req.session.passport.user.userId; 
    deleteFollower(communityId, followerId).then(val => { 
     if(val) res.sendStatus(201); 
     else res.sendStatus(404); 
    }).fail(err => { 
     res.sendStatus(500); 
     errorHelper.diagnosticsUploader(err); 
    }); 
} 

(注意,我個人更喜歡使用bluebird庫性能方面的原因,在這裏我會使用Promise.coroutine)。