Почему эта цепочка обещаний застревает в одном из вызовов, а catch возвращает пустой объект ошибки? - PullRequest
0 голосов
/ 26 июня 2018

Я делаю почтовый запрос, и для этого требуется несколько вещей. Это родной JavaScript обещают не любая библиотека. Первоначально использовалось вложенное обещание, и оно работало, но код был не так хорош. Итак, я решил пойти с цепью Promise, и я застрял. Маршрут post всегда возвращает {success: false, err: {}}, что должно быть, когда что-то идет не так. Но ошибочный объект - пустой объект. Это почему? После некоторых тестов я обнаружил, что проблема во втором, тогда я возвращаю AvaiablexForX.findOne ({isX: false}) ;. Не беспокойтесь об именах переменных, ради идеи я изменил настоящие имена.

router.post("/delevery_request",
            passport.authenticate("jwt", {session:false}),
            (req, res) => {
            const requestInputFields = {};
            const foundxProfile = {};
            const xProfileId = "";
            const newxRequestId = "";
            requestInputFields.isAccepted = false;



            XProfile.findOne({user:req.user.id})
            .then(xProfile => {

                foundxProfile= xProfile;
                requestInputFields.xId = xProfile._id;
                return  AvaiablexForX.findOne({isX:false});
            })

            .then( avaiablexForX => 
                {
                    // this does not reach here
                  console.log("available x for X", avaiablexForX);
                  requestInputFields.xToBeDonateId =  avaiablexForX._id; 
                  xProfileId = avaiablexForX.xProfileId;

                  return requestInputFields;
             })
            .then( result => new RequestxY(result).save()).
            then( requestForxY => {

                foundxProfile.requestedxDeleivery.unshift(requestForxY._id);              
                return foundxProfile.save();

            }).
            then( xProfile => res.json({success:true}))
            .catch(err => {
                        //  output in body of request: {success:false, err:{}}
                        res.status(404).json({success:false, err:err})

            }
            );
          });

Ответы [ 2 ]

0 голосов
/ 26 июня 2018

Краткий ответ: как уже отмечалось, участники, объявленные с const, не могут быть переназначены.

Длинный ответ: вы выиграете от лучшей стратегии для доступа к предыдущим результатам обещания в цепочке .then ()

С ссылкой на связанную тему вы используете "не элегантное и довольно ошибочное" изменяемое контекстное состояние .

Вы могли бы рассмотреть один из других подходов:

  • Закрывающие (и) замыкания
  • Разорвать цепь
  • Явная передача

Например, Вложенные (и) замыкания даст вам что-то вроде этого:

router.post('/delevery_request', passport.authenticate('jwt', { 'session': false }), (req, res) => {
    XProfile.findOne({ 'user': req.user.id })
    .then(xProfile => {
        return AvaiablexForX.findOne({ 'isX': false })
        .then(avaiablexForX => {
            return new RequestxY({
                'isAccepted': false,
                'xId': xProfile._id,
                'xToBeDonateId': avaiablexForX._id
            }).save();
        })
        .then(requestForxY => {
            xProfile.requestedxDeleivery.unshift(requestForxY._id);
            return xProfile.save();
        });
    })
    .then(() => res.json({ 'success': true }))
    .catch(err => {
        res.status(404).json({
            'success': false,
            'err': err
        });
    });
});

Из-за закрытия xProfile доступно для первого и второго вложенных .then().

То, что было requestInputFields, составлено на лету, где оно используется.

Вы теряете хорошую плоскую линию из (), но выигрываете, не нуждаясь в куче грязных внешних членов.

0 голосов
/ 26 июня 2018

Возможно, проблема в том, что вы пытаетесь установить новое значение для const:

foundxProfile= xProfile;

Это вызвало ошибку и разорвало цепь. Попробуйте заменить все const на let.

...