异步函数不是 运行 一些代码甚至在 await 中

Async function not running some code even inside await

我有一个通过无服务器框架创建的 Node.js AWS Lambda 函数。我里面有多个辅助函数。由于异步,我遇到了其中一个问题。函数 运行s 并注销我在旁边放置评论的所有部分,但它不会更新 callDuration。我认为代码由于异步以错误的顺序完成而出现问题。我的目标是能够 return 对 callDuration 我的主要功能进行进一步处理。我怎样才能将所有代码都设为 process/run 并能够实现我的目标并使代码 运行 的顺序正确

函数如下:

const callAggregate = async (billingData, billingDB) => {
    const accountSid = process.env.TWILIO_ACCOUNT_SID
    const authToken = process.env.TWILIO_AUTH_TOKEN
    const client = require('twilio')(accountSid, authToken)
    // Setup model
    const Billing = billingDB.model('Billing')
    await Billing.findOne({_id: billingData._id}).exec().then(bill => {
      const callArray = bill.callSid
      console.log(bill) // This logs out
      let callDuration = 0
      for (const call of callArray) {
        console.log(call) // This logs out
        client.calls(call)
        .fetch()
        .then(callDetails => {
          console.log(callDetails) // This logs out
          callDuration += callDetails.duration
        })
      }
      console.log(`Billing for ${callDuration} minutes of voice calling for ${billingData._id}`) // This logs out
      Billing.findOneAndUpdate(
        {_id: billingData._id},
        { $inc: { call_duration: callDuration }, callSid: []},
        (err, doc) => {
            if(err) {
                console.log(err)
            }
        }
      )
      return callDuration
    })
}

这是一个将 promises 与普通回调混合和匹配以及将 await.then() 混合的情况,这两种情况都使正确的 flow-control 和错误处理管理变得困难。

在你的 async 函数中,在某些地方使用 await,你也有一个你不等待的承诺(这意味着它运行开环,没有任何等待)并且你有一个使用普通回调的数据库函数,而不是 promise 接口,所以也没有什么等待它。

更具体地说,没有什么在等待这个:

client.calls(call).fetch()

因此,由于没有等待 .fetch() 完成,您试图在代码完成修改变量 callDuration 之前使用变量(给您错误的值) .

同样,也没有什么等待 Billing.findOneAndUpdate(...) 完成。

一个干净的解决方案是将所有内容都切换到 promises 和 await。这涉及仅对数据库使用承诺(无普通回调)并将 .then() 处理程序转换为 await.

async function callAggregate(billingData, billingDB) {
    const accountSid = process.env.TWILIO_ACCOUNT_SID
    const authToken = process.env.TWILIO_AUTH_TOKEN
    const client = require('twilio')(accountSid, authToken)
    // Setup model
    const Billing = billingDB.model('Billing')
    let bill = await Billing.findOne({ _id: billingData._id }).exec();
    const callArray = bill.callSid
    console.log(bill) // This logs out
    let callDuration = 0
    for (const call of callArray) {
        console.log(call) // This logs out
        let callDetails = await client.calls(call).fetch();
        console.log(callDetails) // This logs out
        callDuration += callDetails.duration
    }
    console.log(`Billing for ${callDuration} minutes of voice calling for ${billingData._id}`) // This logs out
    let doc = await Billing.findOneAndUpdate({ _id: billingData._id }, { $inc: { call_duration: callDuration }, callSid: [] }).exec();
    return callDuration
}