ESLint の "no-async-promise-executor" ルールとは?


ESLint の "no-async-promise-executor" ルールとは?

エラー処理の困難さ

非同期実行関数内でエラーが発生した場合、そのエラーは Promise に伝達されず、失われてしまいます。これは、問題の特定と修正を困難にし、コードのデバッグを妨げます。

非効率なコード

非同期実行関数で await を使用することは、多くの場合、不要な Promise のネストにつながります。これは、コードを冗長にし、パフォーマンスを低下させる可能性があります。

誤解を招くコード

非同期実行関数で値を返却することは、関数が非同期的に値を生成することを意味する可能性があります。しかし、実際には、resolve 関数を使用して値を手動で設定する必要があります。これは、コードの読解を困難にし、バグの原因となる可能性があります。

このルールを遵守する方法

このルールを遵守するには、Promise コンストラクタの非同期実行関数 で値を返却しないようにする必要があります。代わりに、resolvereject 関数を使用して、Promise の状態を明示的に設定する必要があります。

以下のコードは no-async-promise-executor ルールに違反しています。

async function loadUserData() {
  try {
    const data = await fetch('https://api.example.com/user');
    return data.json();
  } catch (error) {
    return error;
  }
}

このコードを修正するには、以下のように変更する必要があります。

async function loadUserData() {
  try {
    const response = await fetch('https://api.example.com/user');
    const data = await response.json();
    resolve(data);
  } catch (error) {
    reject(error);
  }
}

no-async-promise-executor ルールは、コードの読みやすさ、保守性、およびデバッグ性を向上させるのに役立ちます。すべての JavaScript プロジェクトでこのルールを有効にすることをお勧めします。

  • このルールには、allowVoid オプションがあります。このオプションを true に設定すると、非同期実行関数から void を返すことが許可されます。
  • このルールは、ESLint 6.0.0 で導入されました。


async function loadUserData() {
  const data = await fetch('https://api.example.com/user');
  return data.json();
}

修正例:resolve 関数を使用してPromiseの状態を設定

async function loadUserData() {
  try {
    const response = await fetch('https://api.example.com/user');
    const data = await response.json();
    resolve(data);
  } catch (error) {
    reject(error);
  }
}

違反例:await を使用して非同期操作を実行

new Promise(async (resolve, reject) => {
  const data = await fetch('https://api.example.com/user');
  resolve(data.json());
});

修正例:非同期操作をPromiseの外に実行

new Promise((resolve, reject) => {
  fetch('https://api.example.com/user')
    .then(response => response.json())
    .then(data => resolve(data))
    .catch(error => reject(error));
});

許可例:allowVoid オプションを使用して void を返却

/* eslint no-async-promise-executor: ["error", { "allowVoid": true }] */

async function fetchData() {
  await fetch('https://api.example.com/data');
  // 何もしない
}


"no-async-promise-executor" ルールの代替方法

代替方法

async/await を使用する

最も一般的な代替方法は、async/await を使用して非同期処理を記述することです。これにより、コードがより簡潔で読みやすくなります。

async function loadUserData() {
  try {
    const response = await fetch('https://api.example.com/user');
    const data = await response.json();
    return data;
  } catch (error) {
    return error;
  }
}

Promise.resolve と Promise.reject を使用する

非同期処理をより細かく制御したい場合は、Promise.resolvePromise.reject 関数を使用することができます。

function loadUserData() {
  return new Promise((resolve, reject) => {
    fetch('https://api.example.com/user')
      .then(response => response.json())
      .then(data => resolve(data))
      .catch(error => reject(error));
  });
}

コールバック関数を使用する

古い JavaScript コードでは、コールバック関数を使用して非同期処理を記述することが一般的でした。

function loadUserData(callback) {
  fetch('https://api.example.com/user')
    .then(response => response.json())
    .then(data => callback(null, data))
    .catch(error => callback(error));
}

上記の代替方法が適切でない場合は、no-async-promise-executor ルールを無効にすることができます。ただし、このルールを無効にする場合は、コードが読みやすく、保守しやすく、デバッグしやすいことを確認する必要があります。

/* eslint no-async-promise-executor: "off" */

new Promise(async (resolve, reject) => {
  const data = await fetch('https://api.example.com/user');
  resolve(data.json());
});

適切な方法を選択