首页 > 解决方案 > 异步调用具有多个返回的函数

问题描述

我正在处理的异步函数返回数组中的多个值

const funcName = async function (arg) {
  ...
  return [val1, val2];
}

在调用此函数时,我发现无法直接访问语法中的单个返回值:

result1 = await funcName(arg)[0]  
result2 = await funcName(arg)[1]

它起作用的唯一方法(到目前为止我知道)是将其分解:

result = await funcName(arg)
result1 = result[0]
result2 = result[1]

有没有办法直接在一个 LOC 中“收集”退货?
(非常接近,就像r1 = await fn(x)[0]
这显然适用于同步变体,并保持代码非常精确、干净、可读。

奖金问题:任何线索为什么不支持直接数组访问?
有意为之,还是只是错过了?

标签: javascriptnode.jsasync-await

解决方案


运算符的语法await

await UnaryExpression

这意味着整个表达式将在移交给await. 以下是您遇到的情况的细分await funcName(arg)[0]

  1. funcName(arg)返回一个承诺。

  2. [0]是承诺中使用方括号符号。因此,它0从 promise 对象中获取属性。

  3. 由于没有这样的属性,表达式的结果是undefined

  4. await被调用undefined。由于这不是一个承诺,它被视为 a Promise.resolve(undefined),因此无需等待完成。

  5. 在步骤1.中的实际承诺对象完成之前,代码继续执行。

如果您将表达式的正确部分括在括号中,或者仅在返回 promise 的表达式上使用它,您可以强制await考虑返回的 promise:

const simpleAsync = async function () {
  return ["one", "two"];
}

async function main() {
  const foo = await simpleAsync()[0];
  const bar = (await simpleAsync())[0];
//            ^                   ^ 
  const baz = await simpleAsync();

  console.log("foo:", foo);
  console.log("bar:", bar);
  console.log("baz:", baz);
}

main();

但是,如果您想直接获取两个返回值,您可以简单地使用解构进行多重赋值

const simpleAsync = async function () {
  return ["one", "two"];
}

async function main() {
  const [a, b] = await simpleAsync();

  console.log("a:", a);
  console.log("b:", b);
}

main();

这种方式await是用一个实际的承诺调用的,而不是一个非承诺,在解决之后aandb变量将被分配。


推荐阅读