【问题标题】:Async function not waiting for await异步函数不等待等待
【发布时间】:2023-03-13 02:47:01
【问题描述】:

我有许多异步函数,我从文件中导入 json,然后设置字段。我等待导入 json。早些时候,它通过等待 json 然后操作数据来顺序执行。我以前使用 Mocha,最近开始迁移到 Jest,那时我的所有测试和功能都开始出现问题。

我不确定我是否正确理解了异步函数。但它以前工作得很好,现在不行了。下面是例子:

async build_transaction_request({reference=util.id_generator(), type="XYZ", amount=25, currency="USD", timestamp=util.timestamp_millis()}={}){
    let transactions = await config_util.get_payload("transactions")
    let x_transaction = transactions.xTransaction
    x_transaction.reference = reference
    x_transaction.type = type
    x_transaction.amount = amount
    x_transaction.currency = currency
    x_transaction.timestamp = timestamp
    return x_transaction
}

我得到这个错误:

TypeError:无法设置未定义的属性“引用”

下面是另外两个函数:

async load_data(file_path) {
  await delete require.cache[require.resolve(file_path)]
  let data = await require(file_path);
  return data
}

async get_payload(file_name) {
  let payload = await this.load_data(this.root_dir + '/resources/payload/' + file_name + ".json")
  return payload
}

以下是我的测试中调用 build_transaction_request 函数的代码:

test('Test xyz returns 201', async() => {
      //......some code.....

      var[instruction, x_transaction, token] = await Promise.all([

          helper.build_instruction_request({
            type: "CURRENCY",
            value: value,
            rate: rate
          }),
          helper.build_transaction_request({
            amount: amount
          }),
          helper.build_token_request(token_id)
      ]);
});

【问题讨论】:

  • get_payload 是否返回一个 Promise 对象?其次,你确定这个transactions.xTransaction 不会返回 undefined 吗?
  • 对于初学者来说,您有没有在console.log(transactions); 中查看该对象的实际外观?
  • @Pointy - 如果我运行一个测试,一切正常。但是如果运行测试套件,测试开始失败并且 console.log(transactions);打印未定义。
  • 那么听起来你可能想看看config_util.get_payload()在做什么。
  • @Ele - 是的,get_payload 也是一个异步函数,所以如果我没有错,它应该返回一个承诺。我已经编辑了描述并添加了这两个功能。

标签: javascript node.js async-await jestjs


【解决方案1】:

问题是await config_util.get_payload("transactions") 在解析后返回一个对象,该对象要么缺少xTransaction 属性,要么是使用undefined 手动设置的。一旦你尝试使用undefined 的属性,代码就会爆炸,这就是你正在做的事情:x_transaction.reference = reference。这就像说:undefined.reference = reference.... 因此,这就是代码繁荣的地方。你不能给内存中不存在的东西赋值。

您的get_payload 只是根据您提供给load_data 的一些文件路径来解决一个promise 并返回该结果。

您是否查看了要传递给load_data 的参数?

let payload = await this.load_data(this.root_dir + '/resources  /payload/' + file_name + ".json")

你那里有一个空间,所以它可能不正确。无论您向那里喂什么,它都找不到 json...

【讨论】:

  • 感谢@dvsoukup 的详细解释。我同意问题在于获取数据。这个文件被多个函数访问,然后操作我认为在运行时修改导入文件的数据。是否存在冲突/竞争条件,因为我也在导入缓存之前删除了缓存?
  • 我更新了我的答案,因为......我很傻,这个问题最初并没有出现在我身上。哎呀! :( 罪魁祸首是您传入的文件名。您需要仔细检查您发送的文件路径。
  • 这是一个复制粘贴错误。我已经修改了它。我的代码中的文件路径是正确的。问题是如果我只执行一个测试它就可以了。另外,如果您注意到我正在使用 Promise.all 并行执行承诺并且两个承诺都在访问同一个文件。
【解决方案2】:

所以我发现了问题所在。我改变了导入 json 的方式。现在我正在使用 readFileSync(file_path);现在问题消失了。所以我相信这是由于多个功能同时访问同一个文件。非常感谢大家。

【讨论】:

    猜你喜欢
    • 2019-06-16
    • 2018-02-03
    • 1970-01-01
    • 1970-01-01
    • 2022-07-06
    • 2016-07-07
    • 2016-03-25
    • 2017-10-09
    相关资源
    最近更新 更多