首页 > 解决方案 > 一个异步函数中的多个等待

问题描述

我有一个async包含 3 个等待的函数,如下所示:

const sequenceOfCalls = async(req, res, next) =>{
   await mongoQuery();
   await apiCall1();
   await apiCall2(); 
}

apiCall1使用 的 响应mongoQueryapiCall2使用 的 响应apiCall1

问题是apiCall2无法正常工作(我已经验证了 的所有输入参数apiCall2和响应apiCall1)。

可能有什么问题?请帮忙,因为我已经被困了好几个小时了。

如果您想查看代码,我之前已在此帖子中发布过

编辑
我会尽量做到最具描述性和清晰性。
有关 API 的信息:
我有一个名为 KATM 的 API(仅响应授权的 IP 地址)
他们提供报告,为了获得该报告,我需要执行 3 个步骤:
1)使用 Claim_id 注册客户端
2)发送请求带有之前注册的 Claim_id 的报告。这会以 Token 响应
3) 使用提供的令牌。这最终提供了一份报告。
有关源代码的信息:
我如何注册用户:exports.register = async(req, res, next) => { const body = req.body;

    /* 1. Searching for client in database */
    const client = await Katm_client.findOne({
        name: body.name,
        family_name: body.family_name,
        patronymic: body.patronymic,
    });

    /* 2. If client exists in database */
    if (client) {
        return res.status(500).json({ message: "Client already registered" });
        // throw new Error("Client already exists");//return...ns
    }

    /* 3. If client does not exist in database, create a Client object that will be passed to mongo Model and KATM */
    client_object = {
        claim_id: nanoid(20),
        claim_date: moment().format("DD.MM.YYYY"),
        claim_number: Math.random().toFixed(10).replace("0.", ""),
        agreement_date: moment().format("DD.MM.YYYY"),
        agreement_number: Math.random().toFixed(10).replace("0.",""),
        family_name: body.family_name,
        name: body.name,
        patronymic: body.patronymic,
    };
    const new_client = new Katm_client(client_object)

    /* 4. Make a call to KATM api with Client object */
    const katm_registration = await axios.post(
        'http://10.22.50.3:8000/inquiry/individual',
        {
            header:{ 
                type: "B",
                code: "00433"
            }, 
            request: client_object
            
        },
        {
            headers: {
            'content-type': 'application/json'
            }
        }
        
    );

    /* 5. Handling response from the api */
    if(katm_registration.data.result.code == "05000" && katm_registration.data.result.message == "Успешно"){
        const savedClient = await new_client.save();
        return res.status(200).json({ message: 'Client registered and saved in database.', client: new_client});
    }else{
        return res.status(500).json({ message: katm_registration.data });
    }

接下来我使用一个模块来获取令牌,然后使用它来获取这样的报告:

exports.get_report_credit_info = async(req, res, next) => {
    const body = req.body;

    /* 1. Searching for client in database (Full name is used, but can be changed)*/
    const client = await Katm_client.findOne({
        name: body.name,
        family_name: body.family_name,
        patronymic: body.patronymic
    });

    if (!client) {
        return res.status(401).json({ message: "Client is not registered" });
    }

    /* 2. If client was found in database, make first API call */
    let credit_report;
    try{
        credit_report = await axios.post(
            'http://10.22.50.3:8001/katm-api/v1/credit/report',
            {
                security: {
                    pLogin: 'm',
                    pPassword: 'io',
                },
                data: {
                    pHead: "005",
                    pCode: "00433",
                    pLegal: 1,
                    pClaimId: client.claim_id,
                    pReportId: 8,
                    pReportFormat: 1
                }
            },
            {
                headers: {
                'content-type': 'application/json'
                }
            }
        );
    }catch(err){
        return res.status(400).json({errorMessage: err.message})
    }
    if(!credit_report.data.data.token) return res.status(400).json({message: credit_report.data});
    /* 2. Second API call to get Report */
    status_data = {
        pHead: "005",
        pCode: "00433",
        pToken: credit_report.data.data.token,
        pClaimId: client.claim_id,
        pReportFormat: 1
    }
    console.log(status_data)
    let credit_report_status;
    try{
        credit_report_status = await axios.post(
            'http://10.22.50.3:8001/katm-api/v1/credit/report/status', { data: status_data },
            {
                headers: { 'content-type': 'application/json' }
            }
        );
    }catch(err){
        return res.status(400).json({errorMessage: err.message})
    };
    if(credit_report_status.data.data.result == '05000') return res.status(200).json({ message: 'Client fetched.', clientData64: credit_report_status.data.data.reportBase64});
    else return res.status(400).json({message: credit_report_status.data})
};

我已经尝试过:
我分离了第二个 await( credit_report_status) API 调用以获取报告并且它工作了,但是一旦我添加了第二个 await( credit_report_status) API 调用,它就不再工作了。
我得到一个令牌,这意味着第一个 awaitcredit_report工作正常。我假设第二个 await( credit_report_status) 没有通过或者什么
如你所见,我将 ( credit_report_status) 的入口参数存储为对象,然后将其传递给 Axios。我将其注销以确保它具有正确的信息。
问题是第二个(最后一个)等待(承诺)在 15 次中工作了 1 次。API 没有任何问题,因为我经常用 Postman 检查它

标签: javascriptnode.jsasync-awaitpromise

解决方案


语境

正如您所说,您无法使用调用中的实现,您有两个选择。

第一的

您可以在调用周围创建一个 try catch 块并输出调用可能引发的任何错误。

const sequenceOfCalls = async(req, res, next) =>{
  try {
    await mongoQuery();
    await apiCall1();
    await apiCall2(); 
  } catch (error) {
    // do something with the error, so that you can see it
    console.log(error)
    res.status(400).send('An unexpected error occurred')
  }

  next();
}

第二

如果错误描述性不够,并且您需要知道另一端发生了什么,那么您唯一的选择是联系您正在调用的 API 的维护者。


推荐阅读