Movatterモバイル変換


[0]ホーム

URL:


  1. 開発者向けのウェブ技術
  2. JavaScript
  3. JavaScript リファレンス
  4. 標準組み込みオブジェクト
  5. Array
  6. fromAsync()

このページはコミュニティーの尽力で英語から翻訳されました。MDN Web Docsコミュニティーについてもっと知り、仲間になるにはこちらから。

View in EnglishAlways switch to English

Array.fromAsync()

Baseline 2024
Newly available

Since ⁨January 2024⁩, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

Array.fromAsync() は静的メソッドで、非同期反復可能オブジェクト、反復可能オブジェクト、配列風のオブジェクトから、シャローコピーされた新しい配列インスタンスを作成します。

構文

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

引数

items

配列に変換する非同期反復可能、反復可能、配列風オブジェクトです。

mapFn省略可

配列の各要素に対して呼び出す関数です。指定された場合は、配列に追加するすべての値が最初にこの関数に渡され、mapFn の返値が(待機後に)配列に追加されます。この関数は以下の引数で呼び出されます。

element

items が同期イテレーターまたは配列風オブジェクトの場合、すべての要素が最初に待機状態となり、elementthenable になることはありません。items が非同期反復可能オブジェクトの場合、それぞれの値はそのまま渡されます。

index

配列の、現在処理中の要素のインデックスです。

thisArg省略可

mapFn 実行時にthis として使用する値です。

返値

新しいPromise で、その履行値は新しいArray インスタンスです。

解説

Array.fromAsync() により、以下のものから配列を作成することができます。

Array.fromAsync()for await...of にとてもよく似た方法で非同期反復可能オブジェクトを反復処理します。Array.fromAsync(items) は、以下をの点除いてArray.from() とほぼ同じ動きをします。

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

Array.fromAsync() は、次の点を除いて、動作はArray.from() とほぼ同じです。

  • Array.fromAsync() は非同期反復可能オブジェクトを扱うことができます。
  • Array.fromAsync() は配列インスタンスで履行されるPromise を返します。
  • Array.fromAsync() が非同期反復可能オブジェクトを指定して呼び出された場合、配列に追加する各要素が最初に待機されます。
  • mapFn が指定された場合、その出力も内部で待機されます。

Array.fromAsync()Promise.all() はどちらも、反復可能なプロミスを配列のプロミスに変換することができます。しかし、 2 つの重要な違いがあります。

  • Array.fromAsync() はオブジェクトから得られる値を順番に待ちます。Promise.all() はすべての値を同時に待ちます。
  • Array.fromAsync() は反復可能オブジェクトを遅延的に反復処理し、現在の値が決定するまで次の値を取得しません。Promise.all() はすべての値を事前に取得し、それを待ちます。

非同期反復可能オブジェクトから配列を取得

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]

items が非同期の反復可能オブジェクトであり、それぞれの結果のvalue もプロミスである場合、それらのプロミスは待機されることなく、結果の配列に追加されます。これは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]

メモ:実際には、プロミスを生成する非同期反復可能オブジェクトに遭遇することはほとんどありません。なぜなら、非同期ジェネレータ関数を使用して実装すると、yield 式によってプロミスが自動的にラップ解除されるからです。

同期反復可能オブジェクトから配列を取得

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

プロミスを生成する同期反復可能オブジェクトから配列を取得

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

プロミスの配列風オブジェクトから配列を取得

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]

mapFn を同期反復可能オブジェクトと使用

items が同期反復可能オブジェクトまたは配列風である場合、mapFn の入力と出力は、内部で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]

mapFn を非同期反復可能オブジェクトと使用

items が非同期反復可能オブジェクトの場合、mapFn への入力は待機されませんが、出力は待機されます。上記と同じcreateAsyncIter 関数を使用します。

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

興味深いことに、これはArray.fromAsync(createAsyncIter())Array.fromAsync(createAsyncIter(), (element) => element) と同等ではないことを意味しています。後者はそれぞれの生成値を待機しますが、前者は待機しないからです。

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

Promise.all() との比較

Array.fromAsync() はオブジェクトから得られる値を順番に待ちます。Promise.all() はすべての値を同時に待ちます。

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})();

同期反復可能オブジェクトのエラー処理なし

for await...of と同様に、反復処理されるオブジェクトが同期反復可能オブジェクトで、反復処理中にエラーが発生した場合、基盤となるイテレーターのreturn() メソッドは呼び出されず、イテレーターは閉じられません。

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

イテレーターを閉じる必要がある場合は、代わりにfor...of ループを使用して、各値をawait する必要があります。

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

仕様書

Specification
ES Array.fromAsync
# sec-array.fromAsync

ブラウザーの互換性

関連情報

Help improve MDN

Learn how to contribute

This page was last modified on byMDN contributors.


[8]ページ先頭

©2009-2025 Movatter.jp