JavaScript Promiseについて
🍯Promiseとは
JavaScript
のPromise
オブジェクトは、非同期作業の完了または失敗を表すオブジェクトです。これにより、非同期作業を容易に扱うことができます。
Promise
はコールバック関数の代わりに使用でき、ネストされたコールバック関数の複雑さを減らすことができます。Promise
を使用すると、非同期作業の結果を待ち、その結果に応じて次の作業を連鎖的に実行することができます。
.then()
メソッドを使用して履行状態の結果を処理し、.catch()
メソッドを使用して拒否状態のエラーを処理します。
function test() {
return new Promise(function(resolve, reject) {
$.ajax({
url: '...',
data: '...',
type: 'post',
success : function(response) {
resolve(); //通信成功 resolve()
},
error: function(error) {
reject(new Error('通信失敗')); //通信失敗 reject()
}
});
});
}
//成功関数
function testSuccess() {
console.log("成功");
}
test() //test 実行
.then(testSuccess) //test 成功したら成功関数実行
.catch(console.error); //test 失敗
test( )
を実行し、処理が成功した場合はtestSuccess( )
を実行します。この過程で処理に失敗が発生した場合は、catch(console.error)が出力します。
🍯Promise's states
- 保留(Pending)
- 履行(Fulfilled)
- 失敗(Rejected)
🍮保留(Pending)
Promiseが作成されたばかりで、まだ処理が完了していない状態です。
🍮履行(Fulfilled)
非同期コードが成功裏に実行された状態です。
🍮失敗(Rejected)
失敗した状態、エラーが発生した状態です。
🍯Promiseエラー処理
Promiseのエラーを処理する方法は、then()を2回使用するか、catch()を使用してreject()メソッドが呼び出されて失敗状態になった場合です。可能な限りcatchを使用すべきです。その理由は、thenで処理しようとすると、コールバック関数内で発生するエラーを捕捉できないからです。
getData().then(function(result){
console.log(result);
}).catch(function(err){
console.log('error : ', err);
});
🍯Promise Static methods
🍮Promise.resolve()、Promise.reject()
Promiseを作成した後、すぐに成功したり失敗したりするresolveやrejectを示すことができます。
function kitchen(order) {
return Promise.resolve(`${order}=> 🍝`);
}
function table(vegetable) {
return Promise.resolve(`${vegetable}=>🥗`);
}
function door() {
// return Promise.resolve(`👨👩👧👦`);
// return Promise.reject(new Error("お客さんがいません"));
}
door()
.then((people) => {
return table(people);
})
.then((order) => kitchen(order))
.then((tablesetting) => console.log(tablesetting))
.catch((error) => console.log(error));
resolveの場合
rejectの場合
🍮Promise.all()
function getSusi() {
return new Promise((resolve) => {
setTimeout(() => {
resolve("🍣");
}, 1000);
});
}
function getOcha() {
return new Promise((resolve) => {
setTimeout(() => {
resolve("🍵");
}, 3000);
});
}
function getCookie() {
return Promise.reject(new Error("no cookie"));
}
getSusi() //
.then((susi) =>
getOcha() //
.then((ocha) => [susi, ocha])
)
.then(console.log);
このように呼び出すと、寿司が1秒、お茶が3秒かかるため、合計で4秒かかります。しかし、allを使用すると、並行して実行することができます。
Promise.all([getSusi(), getOcha()]) //
.then((susiya) => console.log("all", susiya));
並行して開始するため、かかる時間は合計で3秒になります。
🍮Promise.race()
与えられたPromiseの中で最も早く実行されたものが出力されます。
Promise.race([getSusi(), getOcha()]) //
.then((menu) => console.log("race", menu));
Promise.allSettled()
Promise.all([getSusi(), getOcha(), getCookie()])
.then((susiya) => console.log("all-error", susiya))
.catch(console.log);
Promise.all()でエラーが発生した場合、エラーがあるため出力されません。
エラーがある場合はallSettledを使用します。失敗しても成功しても、結果を配列にまとめて表示します。
Promise.allSettled([getSusi(), getOcha(), getCookie()])
.then((susiya) => console.log("all-error", susiya))
.catch(console.log);
結論
Promiseの状態、エラー処理方法、そして静的メソッドに関する深層的な分析を通じて、非同期プログラミングの複雑さを解決するのにいかに強力なツールであるかを理解することができました。
個人的に、Promiseは非同期コードをより明確にし、管理しやすくするものであり、特にPromise.allSettledのようなメソッドはさまざまな状況で有用に使えると思います。
Discussion