Node.js Promise チュートリアル

⚡ スマートサマリー

Node.js の Promise は、深くネストされたコールバックを、一度だけ解決される戻り値オブジェクトに置き換えるため、非同期データベース処理は、匿名関数のピラミッドではなく、then 句のフラットな連鎖として読み取ることができます。

  • 🔘 コールバックの問題: ネストされたコールバックは長くなり、保守が困難になる。
  • ☑️ 約束の基本: プロミスは値を返し、一度だけ決済されます。
  • 連鎖: そしてそれ自体がプロミスを返すので、挿入は順番に実行されます。
  • 🧪 お客様一人ひとりに合わせた約束: qライブラリのdenodeifyは、あらゆるコールバックをラップします。
  • 🛠️ 現代の形式: asyncとawaitは、thenコールバックなしでプロミスを処理します。
  • 📊 エラールール: Node.js はバージョン 15 以降、未処理の拒否によって終了します。

Node.js Promiseチュートリアル:コールバックを連鎖させてPromiseを構築する方法

以前のチュートリアルでは、非同期イベントに使用されるコールバック関数について説明しました。しかし、コールバック関数がネストされ、プログラムが長く複雑になり始めると、悪夢になることがあります。

約束とは何ですか?

プロミスについて始める前に、まず「コールバック」関数とは何かを改めて確認しましょう。 Node.jsこれまでの章でこれらのコールバック関数を何度も見てきたので、そのうちの1つを簡単に見ていきましょう。

以下の例は、に接続するために使用されるコード スニペットを示しています。 MongoDB データベースにアクセスし、データベース内のレコードの 1 つに対して更新操作を実行します。

Node.js コールバック関数が接続中 MongoDB 記録を更新する

  1. 上記のコードでは、 function(err,db) の部分は、匿名関数またはコールバック関数の宣言として知られています。 MongoClient が MongoDB データベースでは、接続操作が完了するとコールバック関数に戻ります。つまり、接続操作はバックグラウンドで行われ、完了するとコールバック関数が呼び出されます。これは、多くの操作を同時に実行できるようにし、ユーザーが操作を実行できないようにするための Node.js の重要なポイントの 1 つであることに注意してください。
  2. 2 番目のコード ブロックは、コールバック関数が実際に呼び出されたときに実行されるものです。コールバック関数は単に 1 つのレコードを更新するだけです。 MongoDB データベース。

では、約束とは何でしょうか? まあ、Promise は Node.js のコールバック関数を拡張したものにすぎません。 開発ライフサイクル中に、複数のコールバック関数を一緒にネストする必要がある場合があります。 これは、ある時点で非常に面倒になり、維持するのが困難になる可能性があります。 つまり、Promise は、これらの問題の軽減を目的としたコールバックの機能強化です。

Promise の基本的な構文を以下に示します。

var promise = doSomethingAync()
promise.then(onFulfilled, onRejected)
  • 「doSomethingAync」は、何らかの処理を行うコールバックまたは非同期関数です。
  • 今回、コールバックを定義する際に「promise」と呼ばれる返される値があります。
  • プロミスが返されるとき、2 つの出力を持つことができます。これは、「then 句」によって定義されます。操作は、「onFulfilled」パラメータによって示される成功になるか、「onRejected」パラメータによって示されるエラーになるかのいずれかです。

A 約束 3つの州のうちの1つに位置し、一度定住する。

州/地域 意味
保留中 作業はまだ終わっていません。
成就 onFulfilled は値とともに実行されます。
拒否され onRejected がエラーを伴って実行されます。

注意: したがって、Promise の重要な側面は戻り値です。 Node.js で通常のコールバックを操作する場合、戻り値の概念はありません。 戻り値のおかげで、コールバック関数の定義方法をより詳細に制御できます。

バージョンノート: これらの例はまだ Node.js 24 で実行されています。これは 2026 年のアクティブ LTS ラインです。Node.js 15 以降、 未処理の拒否 警告を表示する代わりにプロセスを終了させるので、すべてのチェーンを .catch() で閉じます。

次のトピックでは、Promise の例と、Promise がコールバックからどのようにメリットを受けるかを見ていきます。

Promise へのコールバック

次に、Node.js アプリケーション内から「promise」を使用する方法の例を見てみましょう。 Node.js アプリケーションで Promise を使用するには、まず「Promise」モジュールをダウンロードしてインストールする必要があります。

次に、以下に示すようにコードを修正し、プロミスを使用して「Employee」コレクション内のEmployeeNameを更新します。

ステップ1) インストール NPMモジュール

Node.jsアプリケーション内でPromiseを使用するには、promiseモジュールが必要です。promiseモジュールをインストールするには、以下のコマンドを実行してください。

npm インストールの約束

ステップ2) コードを変更して Promise を含める

Promiseモジュールの書き換えのエディタのスクリーンショット MongoDB update

var Promise = require('promise');
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost/EmployeeDB';

MongoClient.connect(url)
    .then(function(err, db) {
        db.collection('Employee').updateOne({
            "EmployeeName": "Martin"
        }, {
            $set: {
                "EmployeeName": "Mohan"
            }
        });
    }); 

Code 説明:

  1. 最初の部分は、コード内で Promise 機能を使用できるようにする「Promise」モジュールを含めることです。
  2. これで、「then」関数を MongoClient.connect 関数に追加できるようになりました。 つまり、データベースへの接続が確立されたときに、その後に定義されたコード スニペットを実行する必要があるということです。
  3. 最後に、「Martin」という名前の従業員の EmployeeName を「Mohan」に更新する作業を行うコード スニペットを定義します。

注意:

今、内容を確認してみると、 MongoDB データベースに「Martin」という従業員名を持つレコードが存在する場合、それは「Mohan」に更新されることがわかります。

データがデータベースに正しく挿入されたことを確認するには、次のコマンドを実行する必要があります。 MongoDB

  1. EmployeeDBを使用する
  2. db.Employee.find({EmployeeName : “Mohan”})

最初のステートメントは、EmployeeDBデータベースへの接続を確認します。2番目のステートメントは、従業員名が「Mohan」であるレコードを検索します。

ネストされた Promise の処理

Promise を定義するときは、「then」メソッド自体が Promise を返すことに注意する必要があります。 つまり、ある意味、Promise は互いに入れ子になったり、連鎖したりすることができます。

以下の例では、チェーンを使用して 2 つのコールバック関数を定義しており、どちらもレコードを MongoDB データベース。

(お願い: チェーンとは、メソッドの実行を相互にリンクするために使用される概念です。 アプリケーションに「methodA」と「methodB」という 2 つのメソッドがあるとします。 そして、そのロジックでは、「methodA」の後に「methodB」を呼び出す必要があり、その後、「methodB」が「methodA」の直後に呼び出されるように実行を連鎖させます。)

この例で注目すべき重要な点は、ネストされた Promise を使用することで、コードがよりクリーンで読みやすく、保守しやすくなることです。

連鎖した then 句で 2 つの従業員レコードを挿入します MongoDB

var Promise = require('promise');
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost/EmployeeDB';
MongoClient.connect(url)

.then(function(db) {
    db.collection('Employee').insertOne({
        Employeeid: 4,
        EmployeeName: "NewEmployee"
    })

    .then(function(db1) {
        db1.collection('Employee').insertOne({
            Employeeid: 5,
            EmployeeName: "NewEmployee1"
        })
    })
});

Code 説明:

  1. 現在、順番に実行される 2 つの「then」句を定義しています。 最初の then 句では、データベース接続を含む 'db' パラメータを渡します。 次に、「db」接続のコレクション プロパティを使用して、「Employee」コレクションにレコードを挿入します。 'insertOne' メソッドは、実際のドキュメントを Employee コレクションに挿入するために使用されます。
  2. 次に、2を使用しますnd then 句を使用して、データベースに別のレコードを挿入することもできます。

今、内容を確認してみると、 MongoDB データベースには、2 つのレコードが挿入されています。 MongoDB データベース。

現代の同等語: ES2017以降標準となっているasyncとawaitは、thenコールバックなしでこれらのプロミスを処理し、 ジェネレーターベース co などのフロー制御ライブラリがあり、ネイティブの Promise サポートにより q と bluebird は不要になります。2 番目のブロックでは、db のみを受信して​​いることがわかります。

カスタム Promise の作成

Node.jsモジュール「q」を使用すると、カスタムプロミスを作成できます。「q」ライブラリは、Node Package Managerを使用してダウンロードおよびインストールする必要があります。「q」ライブラリを使用した後、「denodeify」メソッドを呼び出すと、任意の関数がプロミスを返す関数になります。

以下の例では、2 つの数値を加算する「Add」という単純な関数を作成します。この関数を、Promise を返す関数に変換します。

それが完了したら、Add 関数によって返された Promise を使用して、console.log にメッセージを表示します。

以下の手順に従って、Promise を返すカスタム関数を作成してみましょう。

ステップ1) NPM モジュールのインストール

Node.jsアプリケーション内で「q」を使用するには、「q」モジュールが必要です。「q」モジュールをインストールするには、以下のコマンドを実行してください。

npm インストール q

ステップ2) カスタム Promise を作成するために使用される次のコードを定義します。

ラップで構築されたカスタムプロミスping q denodeify を使用した Add 関数

Code 説明:

  1. 最初のビットは、require キーワードを使用して「q」ライブラリをインクルードすることです。 このライブラリを使用すると、コールバックを返す関数を定義できるようになります。
  2. 変数 a と b で定義された 2 つの数値を加算する Add という関数を作成します。これらの値の合計は変数 c に格納されます。
  3. 次に、qライブラリを使用してAdd関数をデノード化(任意の関数をプロミスを返す関数に変換するために使用される方法)します。言い換えれば、Add関数をプロミスを返す関数に変換します。
  4. ここで「Add」関数を呼び出し、Add 関数を denodeify する前に実行したステップにより、戻りの Promise 値を取得できるようになりました。
  5. 「then」キーワードは、関数が正常に実行された場合に、console.log に「Addition function completed」という文字列を表示することを指定するために使用されます。

上記のコードを実行すると、以下に示すように、console.log に「追加機能が完了しました」という出力が表示されます。

コンソール出力:カスタムプロミスから加算関数が完了しました

よくあるご質問

Node.js 15 以降、プロセスは警告ではなくゼロ以外のコードで終了します。すべてのチェーンに .catch() をアタッチするか、 プロセスハンドラ ログを記録して復旧する。

.catch() は、try ブロックなど、チェーンの前の段階で発生したエラーを受け取ります。.finally() は、チェーンが最終的に解決した方法で実行されるため、接続を閉じるのに適しています。

Promise.all は、入力が 1 つでも拒否されるとすぐに失敗します。allSettled は常に解決され、すべての結果が報告されます。race は最初に解決された結果を採用します。any は 1 つの成功が必要で、そうでない場合は AggregateError をスローします。

どちらも同じプロミスを消費します。await は async 関数内で一時停止するため、結果は通常の変数に格納され、エラーは try と catch ブロックに到達します。

まれに。 Generator yield関数はかつてcoのようなライブラリを支えていましたが、asyncとawaitがその役割をネイティブに担っています。 Generators は依然として遅延シーケンスとカスタムイテレータに適しています。

util.promisifyはコールバック形式の関数を直接変換し、fs.promisesなどのモジュールは既にプロミスを返します。どちらも上記のqライブラリを置き換えるものです。

はい。機械学習アナライザーは、拒否ハンドラーのないチェーン、ループ内で待機するチェーン、順序依存の書き込みチェーンにフラグを立て、その結果をランク付けします。 テスト 最も危険な道を選ぶ。

GitHubコパイロット また、同様のエージェントアシスタントはネストされたコールバックを await 呼び出しとしてすばやく書き換えますが、エラー パスと route 意味論は静かに変化する。