「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > JavaScript の約束: 非同期コードの理解、処理、および習得

JavaScript の約束: 非同期コードの理解、処理、および習得

2024 年 11 月 7 日に公開
ブラウズ:178

Promises in JavaScript: Understanding, Handling, and Mastering Async Code

イントロ

私は Java 開発者として働いていましたが、JavaScript の Promise に初めて触れたときのことを覚えています。コンセプトは単純そうに見えましたが、Promise がどのように機能するのかを完全に理解することはできませんでした。プロジェクトでそれらを使用し始め、それらが解決したケースを理解したとき、状況は変わりました。その後、AHA の瞬間が到来し、すべてがより明確になりました。時間が経つにつれて、Promise は私のツールベルトの貴重な武器になりました。仕事でそれらを使用して、関数間の非同期処理を解決できると、妙に満足します。

おそらく、API からデータを取得するときに最初に Promise に遭遇するでしょう。これは最も一般的な例でもあります。最近、インタビューを受けましたが、「Promise と Async Await の違いを教えてください。」という最初の質問は何だったでしょうか。これは、申請者がメカニズムの仕組みをどのように理解しているかをよりよく知るための良い出発点であると考えているため、これを歓迎します。ただし、主に他のライブラリやフレームワークを使用しています。これにより、違いを書き留め、非同期関数のエラーを処理するための優れた実践方法を説明できるようになりました。

約束とは何ですか

最初の質問から始めましょう:「約束とは何ですか?」 Promise はまだ不明な値のプレースホルダーです が、非同期計算/関数の結果として取得されます。約束がうまくいけば、結果が得られます。 Promise がうまくいかない場合、Promise はエラーを返します。

Promise の基本的な例

約束を定義する

Promise を定義するには、コンストラクターを呼び出し、2 つのコールバック関数 resolvereject を渡します。

const newPromise = new Promise((resolve, reject) => {
    resolve('Hello');
    // reject('Error');
});

Promise を正常に解決したい場合は、resolve 関数を呼び出します。拒否は、ロジックの評価中にエラーが発生した場合に、Promise を拒否するためのものです。

Promise 結果の取得

次に、組み込み関数を使用して、Promise の結果を取得します。これには、結果とエラーという 2 つのコールバックが渡されます。 Promise が関数 replace によって正常に解決されると、result が呼び出されます。 Promise が解決されない場合、2 番目の関数エラーが呼び出されます。この関数は、拒否またはスローされた別のエラーによってトリガーされます。

newPromise.then(result => {
    console.log(result); // Hello
}, error => {
    console.log("There shouldn't be an error");
});

この例では、Promise が正常に解決されたため、結果 Hello が得られます。

Promise のエラー処理

Promise が拒否されると、常に 2 番目のエラー コールバックが呼び出されます。

const newPromise1 = new Promise((resolve, reject) => {
  reject('An error occurred in Promise1');
});

newPromise1.then(
  (result) => {
    console.log(result); // It is not invoked
  },
  (error) => {
    console.log(error); // 'An error occurred in Promise1'
  }
);

わかりやすくするためのより推奨されるアプローチは、組み込みの catch メソッドを使用することです。

const newPromise2 = new Promise((resolve, reject) => {
  reject('An error occurred in Promise2');
});

newPromise2
  .then((result) => {
    console.log(result); // It is not invoked
  })
  .catch((error) => {
    console.log(error); // 'An error occurred in Promise2'
  });

catch メソッドはチェーンされており、独自のエラー コールバックを提供しています。 Promise が拒否されたときに呼び出されます。

どちらのバージョンも正常に機能しますが、チェーンは IMO でより読みやすく、さらに説明する他の組み込みメソッドを使用するときに便利です。

約束を連鎖させる

約束の結果は、別の約束になる可能性があります。その場合、任意の数の then 関数を連鎖させることができます。

getJSON('categories.json')
    .then(categories => {
        console.log('Fetched categories:', categories);

        return getJSON(categories[0].itemsUrl);
    })
    .then(items => {
        console.log('Fetched items:', items);

        return getJSON(items[0].detailsUrl);
    })
    .then(details => {
        console.log('Fetched details:', details);
    })
    .catch(error => {
        console.error('An error has occurred:', error.message);
    });

この例では、検索結果を絞り込んで詳細データを取得します。各 then 関数にはエラー コールバックを含めることもできます。呼び出しチェーン内のエラーをキャッチすることだけを気にする場合は、catch 関数を活用できます。いずれかの Promise がエラーを返した場合に評価されます。

みんなと約束してね

場合によっては、より独立した約束の結果を待ち、その結果に基づいて行動したいことがあります。 Promise が解決される順序を気にしない場合は、組み込み関数 Promise.all を使用できます。

Promise.all([
    getJSON('categories.json'),
    getJSON('technology_items.json'),
    getJSON('science_items.json')
])
    .then(results => {
        const categories = results[0];
        const techItems = results[1];
        const scienceItems = results[2];

        console.log('Fetched categories:', categories);
        console.log('Fetched technology items:', techItems);
        console.log('Fetched science items:', scienceItems);

        // Fetch details of the first item in each category
        return Promise.all([
            getJSON(techItems[0].detailsUrl),
            getJSON(scienceItems[0].detailsUrl)
        ]);
    })
    .then(detailsResults => {
        const laptopDetails = detailsResults[0];
        const physicsDetails = detailsResults[1];

        console.log('Fetched laptop details:', laptopDetails);
        console.log('Fetched physics details:', physicsDetails);
    })
    .catch(error => {
        console.error('An error has occurred:', error.message);
    });

Promise.all は Promise の配列を受け取り、結果の配列を返します。 Promise の 1 つが拒否された場合、Promise.all も拒否されます。

レースの約束

もう 1 つの組み込み機能は Promise.race です。これは、複数の非同期関数 (Promise) があり、それらを競合させたい場合に使用されます。

Promise.race([
    getJSON('technology_items.json'),
    getJSON('science_items.json')
])
    .then(result => {
        console.log('First resolved data:', result);
    })
    .catch(error => {
        console.error('An error has occurred:', error.message);
    });

Promise の実行にはさまざまな時間がかかる場合があり、Promise.race は配列から最初に解決または拒否された Promise を評価します。順序は気にしないが、最速の非同期呼び出しの結果が必要な場合に使用されます。

非同期待機とは何ですか

ご覧のとおり、Promise を記述するには多くの定型コードが必要です。幸いなことに、ネイティブの Async Await 機能があるため、Promises の使用がさらに簡単になります。関数を async という単語でマークします。これにより、コードのどこかで非同期関数を呼び出すので、それを待つ必要がないことを示します。次に、await ワードを使用して async 関数が呼び出されます。

非同期待機の基本的な例

const fetchData = async () => {
    try {
        // Fetch the categories
        const categories = await getJSON('categories.json');
        console.log('Fetched categories:', categories);

        // Fetch items from the first category (Technology)
        const techItems = await getJSON(categories[0].itemsUrl);
        console.log('Fetched technology items:', techItems);

        // Fetch details of the first item in Technology (Laptops)
        const laptopDetails = await getJSON(techItems[0].detailsUrl);
        console.log('Fetched laptop details:', laptopDetails);
    } catch (error) {
        console.error('An error has occurred:', error.message);
    }
};

fetchData();

fetchData は async としてマークされており、関数内で await を使用して非同期呼び出しを処理できるようになります。さらに多くの Promise を呼び出すと、それらは次々に評価されます。

エラーを処理したい場合は、try...catch ブロックを使用します。拒否されたエラーは catch ブロックでキャッチされ、エラーをログに記録するように処理できます。

何が違うのか

これらは両方とも、非同期コードを使用した JavaScript 処理の機能です。主な違いは、Promise が then と catch によるチェーンを使用する場合の構文にありますが、async await 構文はより同期的な方法です。読みやすくなります。 async await のエラー処理は、try...catch ブロックを利用するとより簡単になります。面接でよく聞かれる質問です。回答中に、両方の説明をさらに深く掘り下げ、その違いを強調することができます。

約束の機能

もちろん、async await を使用するとすべての機能を使用できます。たとえば、Promise.all.

const fetchAllData = async () => {
    try {
        // Use await with Promise.all to fetch multiple JSON files in parallel
        const [techItems, scienceItems, laptopDetails] = await Promise.all([
            getJSON('technology_items.json'),
            getJSON('science_items.json'),
            getJSON('laptops_details.json')
        ]);

        console.log('Fetched technology items:', techItems);
        console.log('Fetched science items:', scienceItems);
        console.log('Fetched laptop details:', laptopDetails);
    } catch (error) {
        console.error('An error occurred:', error.message);
    }
};

実際の使用例

Promise は、非同期コードを処理するための JavaScript の基本的な機能です。主な使用方法は次のとおりです:

APIからのデータの取得

上記の例ですでに示したように、これは Promise で最もよく使用されるユースケースの 1 つであり、毎日使用します。

ファイル操作の処理

ファイルの非同期的な読み取りと書き込みは、Promise を使用して、特に Node.js モジュール fs.promises によって行うことができます

import * as fs from 'fs/promises';

const writeFileAsync = async (filePath, content, options = {}) => {
    try {
        await fs.writeFile(filePath, content, options);
        console.log(`File successfully written to ${filePath}`);
    } catch (error) {
        console.error(`Error writing file to ${filePath}:`, error.message);
    }
};

const filePath = 'output.txt';
const fileContent = 'Hello, this is some content to write to the file!';
const fileOptions = { encoding: 'utf8', flag: 'w' }; // Optional file write options

writeFileAsync(filePath, fileContent, fileOptions);

Promise ベースのライブラリ

Axios はよく知られているライブラリです。 Axios はクライアントで HTTP リクエストを処理し、広く使用されています。

Express は、Node.js の Web フレームワークです。これにより、Web アプリや API の構築が簡単になり、Express で Promise を使用すると、コードがクリーンな状態に保たれ、管理が容易になります。

例のあるリポジトリ

すべての例は、https://github.com/PrincAm/promise-example

で見つけることができます。

まとめ

Promise は JavaScript の基本的な部分であり、Web 開発で非同期タスクを処理するために不可欠です。データのフェッチ、ファイルの操作、または Axios や Express などの一般的なライブラリの使用にかかわらず、コード内で Promise を頻繁に使用します。

この記事では、Promise とは何か、Promise の結果を定義して取得する方法、エラーを効果的に処理する方法について説明しました。チェーン、Promise.all、Promise.race などの主要な機能についても説明しました。最後に、Promise をより簡単に操作できる async await 構文を導入しました。

JavaScript は毎日使用するツールであるため、これらの概念を理解することは、JavaScript 開発者にとって非常に重要です。

まだ試していない場合は、API からデータをフェッチする簡単なコード スニペットを作成することをお勧めします。まずは楽しい API を試してみてください。さらに、すべての例とコード スニペットがこのリポジトリにあり、探索することができます。

リリースステートメント この記事は次の場所に転載されています: https://dev.to/princam/promises-in-javascript- Understanding-handling-and-mastering-async-code-10kn?1 侵害がある場合は、[email protected] までご連絡ください。それを削除するには
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3