【初心者向け】JavaScriptでPromiseを使いこなす!`catch`と`then`の基礎から応用まで
JavaScript、Node.js、Promiseにおける catch
と then
の配置
JavaScript、Node.jsにおける非同期処理において、Promiseは重要な役割を果たします。Promiseには、処理完了時に実行されるthen
メソッドと、処理失敗時に実行されるcatch
メソッドが用意されています。
本記事では、catch
メソッドとthen
メソッドの配置について、分かりやすく解説します。
catch
メソッドとthen
メソッドの配置
catch
メソッドとthen
メソッドの配置には、2つのパターンがあります。
thenメソッドの前に配置
promise
.catch(error => {
console.error('エラーが発生しました:', error);
})
.then(result => {
console.log('処理が完了しました:', result);
});
この場合、Promiseが拒否された場合のみ、catch
メソッド内の処理が実行されます。Promiseが完了した場合は、catch
メソッドはスキップされ、then
メソッド内の処理が実行されます。
promise
.then(result => {
console.log('処理が完了しました:', result);
})
.catch(error => {
console.error('エラーが発生しました:', error);
});
この場合、Promiseが完了した場合もthen
メソッド内の処理が実行され、その後、Promiseが拒否された場合のみ、catch
メソッド内の処理が実行されます。
どちらの配置が適切か?
どちらの配置が適切かは、状況によって異なります。
- エラー処理を後回しにして、完了処理を優先したい場合
catch
メソッドをthen
メソッドの後に配置します。
- Promiseが拒否された場合、その後の
then
メソッドはスキップされます。 - 複数の
catch
メソッドを連続して配置することもできます。 catch
メソッドは、Promiseチェーンのどこでも配置できます。
例
以下のコードは、非同期処理を2回実行し、いずれかの処理が失敗した場合にエラー処理を行う例です。
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() < 0.5) {
resolve('処理1が完了しました');
} else {
reject(new Error('処理1が失敗しました'));
}
}, 1000);
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() < 0.5) {
resolve('処理2が完了しました');
} else {
reject(new Error('処理2が失敗しました'));
}
}, 2000);
});
promise1
.then(result => {
console.log(result);
return promise2;
})
.catch(error => {
console.error('処理1が失敗しました:', error);
return promise2; // 処理2を継続実行
})
.then(result => {
console.log(result);
})
.catch(error => {
console.error('処理2が失敗しました:', error);
});
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() < 0.5) {
resolve('成功しました');
} else {
reject(new Error('失敗しました'));
}
}, 1000);
});
promise
.catch(error => {
console.error('エラーが発生しました:', error);
})
.then(result => {
console.log('処理が完了しました:', result);
});
このコードでは、50%の確率でPromiseが拒否されます。catch
メソッドがthen
メソッドの前に配置されているため、Promiseが拒否された場合は、catch
メソッド内の処理が実行され、then
メソッドはスキップされます。
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() < 0.5) {
resolve('成功しました');
} else {
reject(new Error('失敗しました'));
}
}, 1000);
});
promise
.then(result => {
console.log('処理が完了しました:', result);
})
.catch(error => {
console.error('エラーが発生しました:', error);
});
このコードでも、50%の確率でPromiseが拒否されます。catch
メソッドがthen
メソッドの後に配置されているため、Promiseが完了した場合もthen
メソッド内の処理が実行され、その後、Promiseが拒否された場合のみ、catch
メソッド内の処理が実行されます。
複数のcatchメソッドを配置
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() < 0.3) {
resolve('成功しました');
} else if (Math.random() < 0.6) {
reject(new Error('エラー1が発生しました'));
} else {
reject(new Error('エラー2が発生しました'));
}
}, 1000);
});
promise
.catch(error => {
console.error('エラーが発生しました:', error.message); // エラーメッセージを取得
})
.catch(error => {
if (error.message === 'エラー1が発生しました') {
console.error('エラー1を補足しました');
}
})
.then(result => {
console.log('処理が完了しました:', result);
});
非同期処理において、エラーが発生した箇所と別の箇所でエラー処理を行う場合があります。
この場合、以下の様にthen
とcatch
を組み合わせることができます。
const asyncFunction = async () => {
try {
const result = await someAsyncOperation();
console.log(result);
} catch (error) {
console.error('エラーが発生しました:', error);
// エラー処理を行う
}
};
asyncFunction();
このコードでは、someAsyncOperation
が非同期処理を実行します。someAsyncOperation
が成功した場合、then
内の処理が実行されます。一方、someAsyncOperation
が失敗した場合、catch
内の処理が実行されます。
エラーハンドリングとデフォルト値の設定
Promiseが拒否された場合、デフォルト値を設定したい場合があります。
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() < 0.5) {
resolve('成功しました');
} else {
reject(new Error('失敗しました'));
}
}, 1000);
});
promise
.then(result => {
console.log('処理が完了しました:', result);
})
.catch(error => {
console.error('エラーが発生しました:', error);
console.log('デフォルト値:', defaultValue); // デフォルト値を設定
});
このコードでは、50%の確率でPromiseが拒否されます。catch
内の処理では、エラーメッセージを出力した後、defaultValue
という変数にデフォルト値を設定します。
複数のPromiseを処理
複数のPromiseを処理し、それぞれ異なる処理を実行したい場合があります。
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() < 0.5) {
resolve('処理1が完了しました');
} else {
reject(new Error('処理1が失敗しました'));
}
}, 1000);
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() < 0.5) {
resolve('処理2が完了しました');
} else {
reject(new Error('処理2が失敗しました'));
}
}, 2000);
});
promise1
.then(result => {
console.log(result);
return promise2;
})
.catch(error => {
console.error('処理1が失敗しました:', error);
return promise2; // 処理2を継続実行
})
.then(result => {
console.log(result);
})
.catch(error => {
console.error('処理2が失敗しました:', error);
});
このコードでは、2つのPromiseを連続して実行します。いずれかのPromiseが拒否された場合、catch
内の処理が実行されますが、その後、残りのPromiseが継続実行されます。
javascript node.js promise