首頁  >  文章  >  web前端  >  掌握非同步 JavaScript:Promise 和 Async/Await 指南

掌握非同步 JavaScript:Promise 和 Async/Await 指南

Susan Sarandon
Susan Sarandon原創
2024-10-06 14:21:03354瀏覽

Mastering Asynchronous JavaScript: A Guide to Promises and Async/Await

JavaScript の非同期の性質は、最新の Web 開発にとって強力かつ不可欠です。 API からのデータの取得からユーザー入力の処理まで、非同期操作は一般的であり、効率的な処理が必要です。 ECMAScript 6 (ES6) の Promises と ECMAScript 2017 の Async/Await の導入により、開発者による非同期コードの処理方法に革命が起こり、コードがよりクリーンで読みやすくなりました。

このブログでは、PromisesAsync/Await、それらがどのように機能するか、JavaScript プロジェクトでいつ使用するかについて説明します。


非同期 JavaScript を理解する

JavaScript はシングルスレッドです。つまり、一度に 1 つの操作のみを実行できます。ただし、ネットワーク リクエスト、ファイル読み取り、タイマーなどの非同期操作を使用すると、メイン スレッドをブロックする可能性があるタスクを JavaScript で処理できるため、ユーザーのアクションに対する応答性が向上します。

Promise と Async/Await が登場する前は、非同期操作は コールバック を使用して処理されていました。これにより、多くの場合 コールバック地獄 - 深くネストされた、保守が困難なコールバック構造。


約束: 一歩前進

Promise は、非同期操作の最終的な完了 (または失敗) を表すオブジェクトです。これにより、コールバックと比較して、より構造化された方法で非同期タスクを処理できます。 Promise は、次の 3 つの状態のいずれかになります。

  • 保留中: 操作はまだ進行中です。
  • 完了: 操作は正常に完了しました。
  • 拒否されました: 操作は失敗しました。

プロミスの作成

Promise を作成するには、解決と拒否という 2 つの引数を持つ関数を渡します。 Promise 内で非同期タスクを実行し、その結果に応じて、resolve (成功した場合) または拒否 (失敗した場合) を呼び出します。


const fetchData = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const data = { name: 'Ishan', age: 25 };
            resolve(data);
        }, 1000);
    });
};


上記の例では、fetchData 関数は、フェッチされたデータを使用して 1 秒後に解決される Promise を返します。

プロミスの消費

Promise の結果は、成功の場合は .then() を使用し、エラーの場合は .catch() を使用して処理できます。


fetchData()
    .then(data => {
        console.log(data); // { name: 'Ishan', age: 25 }
    })
    .catch(error => {
        console.error('Error:', error);
    });


  • .then(): Promise が解決されたときに実行されます。
  • .catch(): Promise が拒否された場合に実行されます。

約束を連鎖させる

Promise の最も強力な機能の 1 つは、複数の非同期操作をチェーンできる機能です。 1 つの .then() の結果を次の .then() に渡すことができます。


fetchData()
    .then(data => {
        return data.name.toUpperCase(); // Modify data
    })
    .then(upperName => {
        console.log(upperName); // 'ISHAN'
    })
    .catch(error => {
        console.error('Error:', error);
    });


Promise コンビネータ

Promise には、複数の非同期操作を同時に処理するのに役立つ組み込みのコンビネータ メソッドもあります。

  • Promise.all(): すべての Promise が解決されるのを待ち、その結果の配列を返します。いずれかの Promise が拒否された場合、Promise 全体が拒否されます。

Promise.all([fetchData(), fetchData()])
    .then(results => console.log(results))
    .catch(error => console.error(error));


  • Promise.race(): 解決または拒否する最初の Promise の結果を返します。

Promise.race([fetchData(), fetchData()])
    .then(result => console.log(result))
    .catch(error => console.error(error));



Async/Await: Promise よりもシュガー構文

Promise は非同期コードの構造化に役立ちますが、複数の非同期操作を扱う場合、.then() 呼び出しの連鎖は依然として複雑になる可能性があります。ここで Async/Await が登場します。ES2017 で導入された async/await を使用すると、同期しているように見える非同期コードを作成できます。

非同期と待機の使用

async/await を使用するには、関数を async としてマークし、その関数内で Promise の前に await キーワードを使用します。これにより、JavaScript は先に進む前に Promise が解決 (または拒否) されるまで待機するようになります。


const fetchData = () => {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve({ name: 'Ishan', age: 25 });
        }, 1000);
    });
};

const getData = async () => {
    const data = await fetchData();
    console.log(data); // { name: 'Ishan', age: 25 }
};

getData();


このコードが、.then() 呼び出しの連鎖に比べてどれほどクリーンであるかに注目してください。同期コードのように読み取れますが、非同期で動作します。

try and catch によるエラー処理

async/await を使用する場合、try/catch でエラーを処理できるため、Promise で .catch() を使用する場合に比べてエラーの管理が容易になります。


const getData = async () => {
    try {
        const data = await fetchData();
        console.log(data);
    } catch (error) {
        console.error('Error:', error);
    }
};

getData();


このアプローチにより、エラー処理がより予測可能になり、すべてのロジックが 1 つのコード ブロックに保持されます。


Promise と Async/Await を使用する場合

Promise と async/await は両方とも、非同期操作を処理するという同じ目標を達成します。では、どのような場合に一方を他方よりも使用すべきでしょうか?

次の場合に Promise を使用します:

  • Promise.all() や Promise.race() などの Promise コンビネータを使用する必要があります。
  • 少数の非同期操作を扱っており、.then() チェーンはまだ管理可能です。

次の場合に非同期/待機を使用します。

  • You want cleaner, more readable code.
  • You have multiple asynchronous operations that rely on each other's results.
  • Error handling needs to be centralized and easier to manage.

Mixing Async/Await with Promise Combinators

One of the advantages of async/await is that it can be combined with promise combinators like Promise.all() to handle multiple asynchronous operations simultaneously.


const fetchData1 = () => {
    return new Promise(resolve => setTimeout(() => resolve('Data 1'), 1000));
};

const fetchData2 = () => {
    return new Promise(resolve => setTimeout(() => resolve('Data 2'), 2000));
};

const getAllData = async () => {
    try {
        const [data1, data2] = await Promise.all([fetchData1(), fetchData2()]);
        console.log(data1, data2); // 'Data 1', 'Data 2'
    } catch (error) {
        console.error('Error:', error);
    }
};

getAllData();


This approach allows you to run promises in parallel while still benefiting from the simplicity of async/await.


Conclusion

Promises and Async/Await are essential tools for managing asynchronous code in JavaScript. While promises provide a structured way to handle async tasks, async/await takes it to the next level by offering a cleaner and more readable syntax. Both approaches have their place, and knowing when to use them will make you a more efficient and effective JavaScript developer.

If you're new to asynchronous JavaScript, start with promises and experiment with async/await to see how they can transform the way you write code.

以上是掌握非同步 JavaScript:Promise 和 Async/Await 指南的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn