2016-12-26 6 views
6

Мы хотели бы сократить количество блоков catch внутри наших обещаний. Если мы удалим вложенные уловы, будут ли исключения забрасываться до родительского улова?Нужны ли вложенные уловы в рамках обещаний?

temporaryUserModel.findOne({email: req.body.email}) 
    .then(tempUser => { 
     if (tempUser) { 
      temporaryUserModel.findOneAndUpdate({_id: tempUser.toJSON()._id}, user) 
       .then((doc) => { 
        return res.status(200).json({ 
         status: 'Success', 
         data: {url: planOpted.chargifySignupUrl} 
        }); 
       }) 
       .catch(err => error(err, res)); 
     } else { 
      temporaryUserModel(user).save() 
       .then((doc) => { 
        return res.status(200).json({ 
         status: 'Success', 
         data: {url: planOpted.chargifySignupUrl} 
        }); 
       }) 
       .catch(err => error(err, res)); 
     } 
    }) 
    .catch(err => error(err, res)); 

Мы хотели бы удалить два вложенных улова и сохранить только улов внизу. Это нормально?

+0

Вы не сказали * почему * Вы хотите удалите внутренние уловы, но я предлагаю посмотреть здесь -> http://bluebirdjs.com/docs/api/catch.html и здесь -> http://bluebirdjs.com/docs/api/promise.all.html – GojiraDeMonstah

+2

вам нужно вернуть свои внутренние обещания, тогда вы можете пузырить свои исключения – hackerrdave

+1

отклонил обещания и, таким образом, '.catch()' будет пузырить цепочку обещаний, если и только если вы возвращаете гостиницу er обещает от '.then()' обработчик, которого вы не являетесь. Это единственный способ, которым внутренние обещания привязаны к внешней цепочке. – jfriend00

ответ

4

Нет, они не будут. Они только подпрыгивают до результата, если вы цепочка ваши обещания, для которых вам нужно return внутренние обещания, созданные обратными вызовами. В противном случае наружное обещание не может дождаться их и не будет знать, когда/как они решаются (выполняют ли они или отклоняют).

temporaryUserModel.findOne({email: req.body.email}).then(tempUser => { 
    if (tempUser) { 
     return temporaryUserModel.findOneAndUpdate({_id: tempUser.toJSON()._id}, user); 
//  ^^^^^^ 
    } else { 
     return temporaryUserModel(user).save(); 
//  ^^^^^^ 
    } 
}).then((doc) => { 
// no need to duplicate this code when you chain anyway 
    return res.status(200).json({ 
     status: 'Success', 
     data: {url: planOpted.chargifySignupUrl} 
    }); 
}).catch(err => error(err, res)); 
+0

Будет ли это работать? return temporUserModel.findOneAndUpdate ({_ id: tempUser.toJSON() ._ id}, user) .then (() => {console.log (1)}); Значение ... будет ли оно работать, если я верну его, а «затем» - в конце? – wayofthefuture

+0

Да, ', then (...)' возвращает обещание, которое вы также можете «возвращать» изнутри обратного вызова. Однако обратите внимание, что если вы только «console.log», значение выполнения станет «undefined». – Bergi

2

Вы можете извлечь некоторые из логики в отдельные функции и return внутренних обещания пузырька любых исключений из посыла цепи:

temporaryUserModel.findOne({email: req.body.email}) 
    .then(updateTempUser) 
    .then(formatResponse) 
    .catch(err => error(err, res)); 

function updateTempUser(tempUser) { 
    if (tempUser) { 
    return temporaryUserModel.findOneAndUpdate({ 
     _id: tempUser.toJSON()._id 
    }, user); 
    } else { 
    return temporaryUserModel(user).save() 
    } 
} 

function formatResponse(doc) { 
    return res.status(200).json({ 
    status: 'Success', 
    data: {url: planOpted.chargifySignupUrl} 
    }); 
}