• Skip to main content
  • Skip to search
  • Skip to select language
HTML

Structure of content on the web

  • Web APIs

    Interfaces for building web applications

  • Learn
    • CSS

      Learn to style content using CSS

    • Overview

      A customized MDN experience

    • FAQ

      Frequently asked questions about MDN Plus

  • HTTP Observatory

    Scan a website for free

  • JavaScript
  • Array.fromAsync()
      • Deutsch
      • 日本語
      • 한국어
      • 中文 (简体)

    In this article

    • Syntax
    • Description
    • Examples
    • Specifications
    • Browser compatibility
    • See also
    1. Array.from()
    2. Array[Symbol.species]
  • Instance methods
    1. Array.prototype.entries()
    2. Array.prototype.find()
    3. Array.prototype.flat()
    4. Array.prototype.indexOf()
    5. Array.prototype.map()
    6. Array.prototype.reduceRight()
    7. Array.prototype.some()
    8. Array.prototype.toReversed()
    9. Array.prototype.unshift()
    10. Array: length
    11. Function.prototype.bind()
    12. Function: displayName Non-standard
    13. Function.prototype.arguments Non-standard Deprecated
    14. Function.prototype.caller Non-standard Deprecated
  • Instance methods
    1. Object.prototype.__defineGetter__() Deprecated
    2. Object.prototype.__defineSetter__() Deprecated
    3. Object.prototype.__lookupGetter__() Deprecated
    4. Object.prototype.__lookupSetter__() Deprecated
    5. Object.prototype.toLocaleString()
    6. Object.prototype.__proto__ Deprecated
    7. iterable, or array-like object.

  • Syntax

    js
    Array.fromAsync(items)
    Array.fromAsync(items, mapFn)
    Array.fromAsync(items, mapFn, thisArg)
    

    Parameters

    items

    An async iterable, iterable, or array-like object to convert to an array.

    mapFn Optional

    A function to call on every element of the array. If provided, every value to be added to the array is first passed through this function, and mapFn's return value is added to the array instead (after being awaited). The function is called with the following arguments:

    element

    The current element being processed in the array. If items is a sync iterable or array-like object, then all elements are first thenable. If items is an async iterable, then each yielded value is passed as-is.

    index

    The index of the current element being processed in the array.

    thisArg Optional

    Value to use as this when executing mapFn.

    Return value

    A new Array instance.

    Description

    Array.fromAsync() lets you create arrays from:

    • AsyncGenerator); or, if the object is not async iterable,
    • Set); or, if the object is not iterable,
    • array-like objects (objects with a length property and indexed elements).

    Array.fromAsync() iterates the async iterable in a fashion very similar to for await...of. Array.fromAsync(items) is generally equivalent to the following code, if items is an async iterable or sync iterable:

    js
    const result = [];
    for await (const element of items) {
      result.push(element);
    }
    

    Array.fromAsync() is almost equivalent to Array.from() in terms of behavior, except the following:

    • Array.fromAsync() handles async iterable objects.
    • Array.fromAsync() returns a Promise that fulfills to the array instance.
    • If Array.fromAsync() is called with a non-async iterable object, each element to be added to the array is first awaited.
    • If a mapFn is provided, its output is also internally awaited.

    Array.fromAsync() and Promise.all() can both turn an iterable of promises into a promise of an array. However, there are two key differences:

    • Array.fromAsync() awaits each value yielded from the object sequentially. Promise.all() awaits all values concurrently.
    • Array.fromAsync() iterates the iterable lazily, and doesn't retrieve the next value until the current one is settled. Promise.all() retrieves all values in advance and awaits them all.

    Examples

    Array from an async iterable

    js
    const asyncIterable = (async function* () {
      for (let i = 0; i < 5; i++) {
        await new Promise((resolve) => setTimeout(resolve, 10 * i));
        yield i;
      }
    })();
    
    Array.fromAsync(asyncIterable).then((array) => console.log(array));
    / [0, 1, 2, 3, 4]
    

    When items is an async iterable where each result's value is also a promise, then those promises are added to the resulting array without being awaited. This is consistent with the behavior of for await...of.

    js
    function createAsyncIter() {
      let i = 0;
      return {
        [Symbol.asyncIterator]() {
          return {
            async next() {
              if (i > 2) return { done: true };
              i++;
              return { value: Promise.resolve(i), done: false };
            },
          };
        },
      };
    }
    
    Array.fromAsync(createAsyncIter()).then((array) => console.log(array));
    / (3) [Promise, Promise, Promise]
    

    Note: In practice, you will rarely encounter an async iterable that yields promises, because if you implement it using an yield expression automatically unwraps promises.

    Array from a sync iterable

    js
    Array.fromAsync(
      new Map([
        [1, 2],
        [3, 4],
      ]),
    ).then((array) => console.log(array));
    / [[1, 2], [3, 4]]
    

    Array from a sync iterable that yields promises

    js
    Array.fromAsync(
      new Set([Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)]),
    ).then((array) => console.log(array));
    / [1, 2, 3]
    

    Array from an array-like object of promises

    js
    Array.fromAsync({
      length: 3,
      0: Promise.resolve(1),
      1: Promise.resolve(2),
      2: Promise.resolve(3),
    }).then((array) => console.log(array));
    / [1, 2, 3]
    

    Using mapFn with a sync iterable

    When items is a sync iterable or array-like object, both the input and output of mapFn are awaited internally by Array.fromAsync().

    js
    function delayedValue(v) {
      return new Promise((resolve) => setTimeout(() => resolve(v), 100));
    }
    
    Array.fromAsync(
      [delayedValue(1), delayedValue(2), delayedValue(3)],
      (element) => delayedValue(element * 2),
    ).then((array) => console.log(array));
    / [2, 4, 6]
    

    Using mapFn with an async iterable

    When items is an async iterable, the input to mapFn is not awaited, but the output is. Using the same createAsyncIter function as above:

    js
    Array.fromAsync(createAsyncIter(), async (element) => (await element) * 2).then(
      (array) => console.log(array),
    );
    / [2, 4, 6]
    

    Curiously, this means that Array.fromAsync(createAsyncIter()) is not equivalent to Array.fromAsync(createAsyncIter(), (element) => element), because the latter awaits each yielded value, while the former does not.

    js
    Array.fromAsync(createAsyncIter(), (element) => element).then((array) =>
      console.log(array),
    );
    / [1, 2, 3]
    

    Comparison with Promise.all()

    Array.fromAsync() awaits each value yielded from the object sequentially. Promise.all() awaits all values concurrently.

    js
    function* makeIterableOfPromises() {
      for (let i = 0; i < 5; i++) {
        yield new Promise((resolve) => setTimeout(resolve, 100));
      }
    }
    
    (async () => {
      console.time("Array.fromAsync() time");
      await Array.fromAsync(makeIterableOfPromises());
      console.timeEnd("Array.fromAsync() time");
      / Array.fromAsync() time: 503.610ms
    
      console.time("Promise.all() time");
      await Promise.all(makeIterableOfPromises());
      console.timeEnd("Promise.all() time");
      / Promise.all() time: 101.728ms
    })();
    

    No error handling for sync iterables

    Similar to for await...of, if the object being iterated is a sync iterable, and an error is thrown while iterating, the return() method of the underlying iterator will not be called, so the iterator is not closed.

    js
    function* generatorWithRejectedPromises() {
      try {
        yield 0;
        yield Promise.reject(new Error("error"));
      } finally {
        console.log("called finally");
      }
    }
    
    (async () => {
      try {
        await Array.fromAsync(generatorWithRejectedPromises());
      } catch (e) {
        console.log("caught", e);
      }
    })();
    / caught Error: error
    / No "called finally" message
    

    If you need to close the iterator, you need to use a for...of loop instead, and await each value yourself.

    js
    (async () => {
      const arr = [];
      try {
        for (const val of generatorWithRejectedPromises()) {
          arr.push(await val);
        }
      } catch (e) {
        console.log("caught", e);
      }
    })();
    / called finally
    / caught 3
    

    Specifications

    Specification
    ES Array.fromAsync
    # sec-array.fromAsync

    Browser compatibility

    See also

    • Polyfill of Array.fromAsync in core-js
    • Indexed collections guide
    • Array
    • Array()
    • Array.of()
    • Array.from()
    • for await...of

    Help improve MDN

    Array.fromAsync() static method copies items from an async iterable object to make a new array.","name":"Array.fromAsync()"}},"browserCompat":["javascript.builtins.Array.fromAsync"],"pageType":"javascript-static-method"}}

    Follow Lee on X/Twitter - Father, Husband, Serial builder creating AI, crypto, games & web tools. We are friends :) AI Will Come To Life!

    Check out: eBank.nz (Art Generator) | Netwrck.com (AI Tools) | Text-Generator.io (AI API) | BitBank.nz (Crypto AI) | ReadingTime (Kids Reading) | RewordGame | BigMultiplayerChess | WebFiddle | How.nz | Helix AI Assistant