1. ホーム
  2. javascript

[解決済み] Node.jsのコールバックをプロミスに置き換える

2023-02-02 05:12:04

質問

データベースに接続するシンプルなノードモジュールで、データを受け取るためのいくつかの関数を持っています。


dbConnection.jsです。

import mysql from 'mysql';

const connection = mysql.createConnection({
  host: 'localhost',
  user: 'user',
  password: 'password',
  database: 'db'
});

export default {
  getUsers(callback) {
    connection.connect(() => {
      connection.query('SELECT * FROM Users', (err, result) => {
        if (!err){
          callback(result);
        }
      });
    });
  }
};

このモジュールは、別のノードモジュールからこのように呼ばれることになります。


app.js:

import dbCon from './dbConnection.js';

dbCon.getUsers(console.log);

データを返すために、コールバックの代わりにプロミスを使用したいと思います。 今のところ、私は以下のスレッドでネストされたプロミスについて読みました。 ネストされたプロミスできれいなコードを書く しかし、私はこのユースケースのために十分に単純なソリューションを見つけることができませんでした。 を返すための正しい方法は何でしょうか? result をプロミスで返す正しい方法は何でしょうか?

どのように解決するのですか?

を使用して Promise クラス

を見てみることをお勧めします。 MDN の Promise ドキュメント を見てみることをお勧めします。これはプロミスを使うための良い出発点を提供します。あるいは、多くのチュートリアルがオンラインで利用可能であると思います。)

注意してください。 最近のブラウザはすでにECMAScript 6のプロミス仕様をサポートしており(上記リンク先のMDNドキュメントを参照)、サードパーティライブラリなしのネイティブ実装を使用したいのだと思います。

実際の例として...

基本的な原理はこのようになります。

  1. あなたのAPIは
  2. 新しいPromiseオブジェクトを作成します。このオブジェクトはコンストラクタのパラメータとして1つの関数を取ります。
  3. あなたが提供した関数は、基礎となる実装によって呼び出され、その関数は2つの関数 - を与えられます。 resolvereject
  4. ロジックを作成したら、これらのいずれかを呼び出して、Promiseを満たすか、エラーで拒否します。

たくさんあるように見えるかもしれませんので、実際の例を挙げます。

exports.getUsers = function getUsers () {
  // Return the Promise right away, unless you really need to
  // do something before you create a new Promise, but usually
  // this can go into the function below
  return new Promise((resolve, reject) => {
    // reject and resolve are functions provided by the Promise
    // implementation. Call only one of them.

    // Do your logic here - you can do WTF you want.:)
    connection.query('SELECT * FROM Users', (err, result) => {
      // PS. Fail fast! Handle errors first, then move to the
      // important stuff (that's a good practice at least)
      if (err) {
        // Reject the Promise with an error
        return reject(err)
      }

      // Resolve (or fulfill) the promise with data
      return resolve(result)
    })
  })
}

// Usage:
exports.getUsers()  // Returns a Promise!
  .then(users => {
    // Do stuff with users
  })
  .catch(err => {
    // handle errors
  })

async/await言語機能を使う (Node.js >=7.6)

Node.js 7.6では、v8のJavaScriptコンパイラがバージョンアップされ async/awaitのサポート . として関数を宣言できるようになりました。 async であると宣言できるようになりました。 Promise を返し、非同期関数の実行が完了した時点で解決されます。この関数の内部では await キーワードを使用して、別の Promise が解決されるまで待機します。

以下はその例です。

exports.getUsers = async function getUsers() {
  // We are in an async function - this will return Promise
  // no matter what.

  // We can interact with other functions which return a
  // Promise very easily:
  const result = await connection.query('select * from users')

  // Interacting with callback-based APIs is a bit more
  // complicated but still very easy:
  const result2 = await new Promise((resolve, reject) => {
    connection.query('select * from users', (err, res) => {
      return void err ? reject(err) : resolve(res)
    })
  })
  // Returning a value will cause the promise to be resolved
  // with that value
  return result
}