为什么将 flatMap 与异步函数一起使用不会返回展平数组?

max*_*tSO 6 javascript typescript flatmap

我想了解为什么使用.flatMap()withasync不会返回展平数组。

例如,对于 Typescript,这会返回一个数字数组: 我知道,对于简单的数字数组来说是没有用的,它只是更容易Promisse.all复制async

const numbers = [[1], [2], [3]];
// typed as number[]
const numbersFlatten = await Promise.all(
    numbers.flatMap((number) => number),
);
Run Code Online (Sandbox Code Playgroud)

对于 Typescript,当这返回一个数字数组的数组时(刚刚添加了一个异步):

const numbers = [[1], [2], [3]];
// typed as number[][]
const numbersFlatten = await Promise.all(
    numbers.flatMap(async (number) => number),
);
Run Code Online (Sandbox Code Playgroud)

Nic*_*ons 11

所有async函数都隐式返回 Promise。通过进行.flatMap()回调async,它现在返回一个解析为number数组中的 Promise。为了.flatMap()正确工作并使其结果扁平化,回调应该返回一个数组,而不是 Promise。以下是有问题的行为的示例:

const numbers = [[1], [2], [3]];
const promiseAllArg = numbers.flatMap(async (number) => number); // same as `.flatMap(number => Promise.resolve(number))`, flatMap doesn't know how to flatten `Promise<number>` into a resulting array
console.log(promiseAllArg); // [Promise<[1]>, Promise<[2]>, Promise<[3]>]
Run Code Online (Sandbox Code Playgroud)

相反,您可以使用常规.map()调用来获取解析值的嵌套数组,然后.flat()调用:

(async () => {
  const numbers = [[1], [2], [3]];
  const awaitedNumbers = await Promise.all(
    numbers.map(async (number) => number) // some async code
  );
  const numbersFlattened = awaitedNumbers.flat() // flatten the resolved values
  console.log(numbersFlattened);
})();
Run Code Online (Sandbox Code Playgroud)

  • [^](/sf/ask/5247148931/#comment132279982_74959389)“_为什么承诺不能在数组中展平_”:@maximeSurmontSO **展平**数组意味着连接子数组元素。因为 Promise 不是数组,所以它们不能被展平。请参阅:[`Array.prototype.flat()` - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat) (2认同)
  • @maximeSurmontSO 另外,承诺并不一定有价值。它是一个在 .flatMap() 创建其数组时可能处于挂起状态的对象(意味着它尚未“保存”任何值)。只有在未来的某个时候,promise 才可能变为已解决的状态,并在该状态下保持一定的值。为了使 `.flatMap()` 能够与 Promises 一起正常工作,它在内部需要等待每个 Promises 解析,然后将解析的值合并到其结果数组中,但它不会这样做(因为 `.flatMap()` 不是异步)。在内部,它仅将数组展平为最终结果 (2认同)