JavaScript Promises - reject vs. throw の分かりやすい解説
JavaScript Promises - reject vs. throw の分かりやすい解説
JavaScript の Promise は、非同期処理を扱うための強力なツールです。Promise には、resolve
と reject
という 2 つの重要なメソッドがあります。resolve
は操作が成功したことを示し、reject
は操作が失敗したことを示します。
このチュートリアルでは、reject
と throw
の違いを明確にし、それぞれの使用方法を説明します。
reject
と throw
はどちらもエラーを報告するために使用できますが、いくつかの重要な違いがあります。
- スコープ:
reject
は Promise 内でのみ使用できます。
- エラー処理:
reject
は Promise のcatch
メソッドで処理されます。throw
は try-catch ブロックで処理されます。
- 同期/非同期:
reject
は非同期的に実行されます。Promise が完了した後に実行されます。throw
は同期的に実行されます。コードの実行をすぐに停止します。
reject の使用方法
reject
メソッドは、Promise を拒否するために使用されます。拒否された Promise は、catch
メソッドを使用して処理できます。
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.5) {
resolve("Success!");
} else {
reject(new Error("Failed!"));
}
}, 1000);
});
promise
.then((result) => console.log(result))
.catch((error) => console.error(error));
この例では、promise
は 50% の確率で成功し、50% の確率で失敗します。成功した場合、resolve
メソッドは "Success!" を呼び出し、Promise は解決されます。失敗した場合、reject
メソッドは Error
オブジェクトを呼び出し、Promise は拒否されます。
throw の使用方法
throw
キーワードは、エラーを生成するために使用されます。エラーは try-catch ブロックで処理できます。
function loadUser(userId) {
if (userId === 1) {
return { name: "Alice" };
} else {
throw new Error("Invalid user ID");
}
}
try {
const user = loadUser(2);
console.log(user.name);
} catch (error) {
console.error(error);
}
この例では、loadUser
関数は、ユーザー ID が 1 の場合にユーザー オブジェクトを返します。それ以外の場合は、Error
オブジェクトをスローします。
一般的に、Promise 内でエラーを報告するには reject
を使用し、Promise 外でエラーを報告するには throw
を使用することをお勧めします。
- Promise 内:
reject
は Promise の状態を明確に示すため、より適切です。catch
メソッドを使用してエラーを処理できます。
- Promise 外:
throw
はコードの実行を停止するため、より適切です。
reject
と throw
はどちらも JavaScript でエラーを報告するために使用できますが、それぞれ異なる目的があります。状況に応じて適切な方法を選択することが重要です。
例 1: reject を使用した非同期エラー処理
この例では、非同期操作 (API 呼び出しなど) をシミュレートする関数 loadUserData
を作成します。この関数は、成功時にユーザー データを解決し、失敗時にエラーを拒否します。
function loadUserData(userId) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (userId === 1) {
resolve({ name: "Alice", age: 30 });
} else {
reject(new Error("Invalid user ID"));
}
}, 1000);
});
}
loadUserData(1)
.then((userData) => {
console.log(`User loaded: ${userData.name}, ${userData.age}`);
})
.catch((error) => {
console.error(`Failed to load user: ${error.message}`);
});
この例では、ユーザー入力の検証を行う関数 validateUserInput
を作成します。この関数は、入力値が有効な場合に true
を返し、そうでない場合は Error
オブジェクトをスローします。
function validateUserInput(name, email) {
if (!name || name.trim() === "") {
throw new Error("Name is required");
}
if (!email || email.trim() === "") {
throw new Error("Email is required");
}
return true;
}
try {
const isValid = validateUserInput("", "[email protected]");
console.log("Validation successful");
} catch (error) {
console.error(`Validation failed: ${error.message}`);
}
この例では、Promise 内で throw
を使用してエラーを報告する方法を示します。これは、Promise チェーン内のエラー処理を簡潔にするのに役立ちます。
function loadUserAndGreeting(userId) {
return new Promise((resolve, reject) => {
loadUserData(userId)
.then((user) => {
const greeting = `Hello, ${user.name}!`;
resolve(greeting);
})
.catch((error) => {
throw error; // エラーを Promise チェーンに伝播
});
});
}
loadUserAndGreeting(2)
.then((greeting) => {
console.log(greeting);
})
.catch((error) => {
console.error(`Failed to load user and greeting: ${error.message}`);
});
JavaScript Promisesでエラー処理を行うその他の方法
Promise.finally
は、Promiseチェーンの完了後、常に実行される非同期操作です。Promiseが成功または失敗に関係なく実行されます。これは、クリーンアップ操作を実行したり、ログを記録したりするのに役立ちます。
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.5) {
resolve("Success!");
} else {
reject(new Error("Failed!"));
}
}, 1000);
});
promise
.then((result) => console.log(result))
.catch((error) => console.error(error))
.finally(() => console.log("Promise completed"));
Promise.all
は、複数のPromiseを同時に実行し、すべて完了した後に結果を返す関数です。いずれかのPromiseが失敗すると、全体のPromiseが失敗し、catch
メソッドでエラーを処理できます。
const promise1 = Promise.resolve("Success!");
const promise2 = Promise.reject(new Error("Failed!"));
Promise.all([promise1, promise2])
.then((results) => console.log(results))
.catch((error) => console.error(error));
Promise.race
は、最初に解決または拒否されたPromiseに基づいて結果を返す関数です。どちらのPromiseが先に完了しても、全体のPromiseは完了し、then
またはcatch
メソッドで結果を処理できます。
const promise1 = new Promise((resolve) => setTimeout(() => resolve("Slow"), 2000));
const promise2 = new Promise((resolve, reject) => setTimeout(() => reject(new Error("Fast")), 1000));
Promise.race([promise1, promise2])
.then((result) => console.log(result))
.catch((error) => console.error(error));
async/await
は、Promiseをより同期的に扱うための構文です。非同期操作を待機し、変数に結果を格納することができます。
async function loadUserData(userId) {
try {
const response = await fetch(`https://api.example.com/users/${userId}`);
const data = await response.json();
return data;
} catch (error) {
console.error(`Failed to load user: ${error.message}`);
return null;
}
}
(async () => {
const user = await loadUserData(1);
if (user) {
console.log(`User loaded: ${user.name}, ${user.age}`);
}
})();
これらの方法は、それぞれ異なるユースケースに適しています。状況に応じて適切な方法を選択することが重要です。
javascript promise