为什么此promise链卡在随后的调用中,然后catch返回空错误对象?

时间:2018-06-26 09:47:35

标签: javascript promise es6-promise

我正在发出发帖请求,它需要完成几件事。它是本机JavaScript,不会提供任何库。最初使用嵌套的promise,它可以工作,但是代码不是那么好。因此,我决定选择Promise连锁店,但我陷入了困境。发布路由始终返回{success:false,err:{}},当出现问题时应该返回该路由。但是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 :(得分:0)

可能的问题是您尝试为const设置新值:

foundxProfile= xProfile;

这导致错误并中断了链。尝试将所有const替换为let

答案 1 :(得分:0)

简短的回答:已经指出,用const声明的成员无法重新分配。

长答案:您将受益于accessing previous promise results in a .then() chain的更好策略

参考链接的主题,您使用的是“模糊且容易出错”的可变上下文状态

您可以考虑其他方法之一:

  • 嵌套(和)关闭
  • 破坏链条
  • 显式传递

例如,嵌套(和)闭包将为您提供以下信息:

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是由使用时动态组成的。

您失去了then()的漂亮扁平排列,但是不需要一堆凌乱的外部成员。