为什么代码内的catch语句无法捕获异步函数中的错误?

时间:2019-06-19 05:25:06

标签: javascript node.js async-await

我在promise返回中有一个.then,并且我定义了一个异步函数,该函数从API获取一些数据。我卡住的部分是,当我抛出一个错误(强制)时,它不会被catch块捕获。

据我了解,对于所有.then语句,一个.catch就足够了。这是因为代码中还有另一个异步函数,因此.catch无法正常工作吗?

CampaignController.getOnboardingCampaignList = (req,res) => {

    return OnBoardingCampaign.find({description : {$exists : true}},{name: 1, description : 1, suggestedHaikuIds : 1})
    .then((r) => {
      // Some Logic here, unrelated the the work done below

        async function getSuggestedHaiku(){
            for(const campaign of r ){
                let suggestedHaikuIds = [];
                campaign.suggestedHaikus = [];
                throw new Error; // Using this to throw the new error
                if(campaign.suggestedHaikuIds === '') campaign.suggestedHaikuIds = [];
                else{
                    campaign.suggestedHaikuIds.forEach((id) => {
                        suggestedHaikuIds.push(Helper.parseId(id))
                    }) // This particular line threw the error initially
                    const result = await SuggestedHaiku.find({_id: {$in : suggestedHaikuIds}},{timeStamp : 0, deleted : 0, returnCount : 0, writtenCount : 0});

                    campaign.suggestedHaikus = result;
                }

            }

            if(r.length === 0){
                return Promise.reject(1001);
            }else{
                let result = {};
                result.list = r;
                Helper.success(res,"Onboarding Campaign List",result);
            }
        }
        getSuggestedHaiku();    


    })
    .catch(err => Helper.error(res, err)) // This catch did not catch the error thrown above

}

错误消息如下

UnhandledPromiseRejectionWarning:错误     在getSuggestedHaiku(/Users/abhinav/haikuserver/controllers/campaign.js:242:23)     在OnBoardingCampaign.find.then(/Users/abhinav/haikuserver/controllers/campaign.js:263:9)     在process._tickCallback(内部/进程/next_tick.js:68:7) warning.js:18 (节点:7646)UnhandledPromiseRejectionWarning:未处理的承诺拒绝。引发此错误的原因可能是抛出了一个没有catch块的异步函数,或者是拒绝了一个.catch()无法处理的承诺。 (拒绝ID:2) warning.js:18 (节点:7646)[DEP0018] DeprecationWarning:已弃用未处理的承诺拒绝。将来,未处理的承诺拒绝将以非零退出代码终止Node.js进程。

2 个答案:

答案 0 :(得分:0)

Javascript执行命令而不必等待先前的功能/命令完成。到您的异步功能完成并引发错误时,控制流已经移到catch块的前面。

因此,当发生错误/承诺被拒绝时,事件循环中没有剩余的catch块来处理它。

答案 1 :(得分:0)

try catch应该包装为for循环。

try{

      for(const campaign of r ){}

}catch() {}