JavaScript - 非同期イテレーション
こんにちは、未来のJavaScriptの魔法使いたち!今日は、非同期イテレーションの世界への興味深い旅に出発します。これらの言葉が少し威圧的だと思われるかもしれませんが、このレッスンの終わりまでに、あなたはこれらの強力な概念をプロのように堂々と使いこなすことができるでしょう。それでは、さっそく始めましょう!
非同期イテレーション
非同期イテレーションとは?
imagine you're at a busy coffee shop. You place your order, but instead of waiting at the counter, you sit down and chat with friends while your coffee is being prepared. That's essentially what asynchronous operations are in programming – you start a task and then move on to other things while waiting for it to complete.
非同期イテレーションはこの概念を一歩進めます。あなたが複数のコーヒーを注文し、それぞれが準備ができ次第あなたに運ばれてくる、那样的なものです。カウンターで確認する必要はありません。
JavaScriptでは、非同期イテレーションにより、バックグラウンドで発生している操作にもかかわらず、自然で順序的な方法で非同期データソースを扱うことができます。
非同期操作の理解
非同期イテレーションに進む前に、まずJavaScriptにおける非同期操作を理解しましょう。
プロミス:基本概念
プロミスは非同期JavaScriptの基本概念です。将来のいつか解決される値を表します。
以下に簡単な例を示します:
let coffeePromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Your coffee is ready!");
}, 2000);
});
coffeePromise.then((message) => {
console.log(message);
});
この例では、coffeePromise
はコーヒーを淹れるプロセスをシミュレートしています。2秒後(淹れ時間をシミュレート)、メッセージで解決します。then
メソッドは解決されたプロミスを処理するために使用されます。
Async/Await:プロミスのためのシンタックスシュガー
async/await
シンタックスは、プロミスをより簡単に扱うために使用されます。非同期コードを同期コードのように見せることができます。
async function getCoffee() {
let message = await new Promise((resolve) => {
setTimeout(() => {
resolve("Your coffee is ready!");
}, 2000);
});
console.log(message);
}
getCoffee();
このコードは前の例と同じことをしていますが、より読みやすく理解しやすいように書かれています。
'for await...of'ループの使用
非同期操作を理解したところで、for await...of
ループを使用してそれらをイテレートする方法を見てみましょう。
基本構文
for await...of
ループの基本構文は以下の通りです:
async function example() {
for await (let value of asyncIterable) {
console.log(value);
}
}
実用的な例
非同期関数でコーヒー注文をシミュレートする例を見てみましょう:
async function* coffeeOrders() {
yield await Promise.resolve("Espresso");
yield await Promise.resolve("Latte");
yield await Promise.resolve("Cappuccino");
}
async function serveCoffee() {
for await (let coffee of coffeeOrders()) {
console.log(`Serving: ${coffee}`);
}
}
serveCoffee();
この例では、coffeeOrders
はコーヒー注文を生成する非同期ジェネレータ関数です。serveCoffee
関数はfor await...of
ループを使用してこれらの注文をイテレートし、利用可能になるたびに提供します。
実際の使用ケース
非同期イテレーションは、データのストリームや大量データをチャンクごとに処理する必要がある場合に特に役立ちます。
大きなファイルの読み取り
非常に大きなファイルを一行ずつ読み取る例を見てみましょう:
const fs = require('fs').promises;
async function* readLines(file) {
const fileHandle = await fs.open(file, 'r');
const stream = fileHandle.createReadStream();
let buffer = '';
for await (const chunk of stream) {
buffer += chunk;
let lineEnd;
while ((lineEnd = buffer.indexOf('\n')) !== -1) {
yield buffer.slice(0, lineEnd);
buffer = buffer.slice(lineEnd + 1);
}
}
if (buffer.length > 0) {
yield buffer;
}
await fileHandle.close();
}
async function processFile() {
for await (const line of readLines('largefile.txt')) {
console.log(`Processing line: ${line}`);
}
}
processFile();
この例では、非同期イテレーションを使用して、ファイル全体をメモリに読み込むことなく、一行ずつ処理することができます。
ページ네ーションAPIデータの取得
別の一般的な使用ケースは、APIからページごとにデータを取得することです:
async function* fetchPages(url) {
let nextUrl = url;
while (nextUrl) {
const response = await fetch(nextUrl);
const data = await response.json();
yield data.items;
nextUrl = data.next;
}
}
async function processAllPages() {
for await (const page of fetchPages('https://api.example.com/data')) {
for (const item of page) {
console.log(`Processing item: ${item.name}`);
}
}
}
processAllPages();
この例では、非同期イテレーションを使用して、APIからページごとにデータを取得し、各ページを取得するたびに処理します。
結論
非同期イテレーションは、非同期データソースをクリーンで直感的な方法で扱うための強力なツールです。データのストリームや大量データをチャンクごとに処理する必要がある場合に特に役立ちます。
忘れてはならないのは、非同期イテレーションをマスターするためには練習が重要です。これらの概念を自分のプロジェクトで実験してみてください。間もなく、あなたは真のJavaScriptの ninja として非同期操作を扱えるようになるでしょう!
メソッド | 説明 |
---|---|
for await...of |
非同期イテレーションオブジェクトをイテレートするために使用されます |
async function* |
非同期ジェネレータ関数を定義します |
yield |
ジェネレータ関数内でイテレートする値を定義します |
Promise.resolve() |
指定された値で解決されたプロミスを作成します |
async/await |
プロミスをより同期コードのように扱うためのシンタックス |
ハッピーコーディング、そしてあなたの非同期操作が常に解決されることを祈っています!
Credits: Image by storyset