1. Promiseとは?
Promiseとはその名の通り約束のことです。
Promiseを使う場合は何かの処理を施して、その結果が戻ってくることが約束されています。
結果は**成功(Resolve)もしくは失敗(Reject)**のどちらかの方法で帰って来ます。
const iceCreams = ["strawberry", "chocolate", "vanilla"];
const iceCreamType = "lemon";
getIceCream = (iceCreamType) => {
return new Promise((resolve, reject) => {
if(iceCreams.indexOf(iceCreamType) > -1){
resolve(iceCreamType);
} else {
reject("There is no ice cream");
}
};
}
ここの関数では、アイスクリームがあるかどうか確認しています。この場合、配列の中に"lemon"がなかったので、Reject()が帰ってきます。
エラーハンドリングする時に超便利です。
2. Promiseの同期処理
Promiseの良いところは非同期処理ができるところです。例えば、上記のように同時処理を行いたいときは、以下の様に書ける.
const getIceCream = () => new Promise((resolve, reject) => { ... });
const getFood = () => new Promise((resolve, reject) => { ... });
const getDrink = () => new Promise((resolve, reject) => { ... });
const [ iceCream, food, drink ] = await Promise.all([
getIceCream(),
getFood(),
getDrink(),
]);
return { iceCream, money, food };
awaitを前に置くと、処理が終わるまで待ってくれます。
ただし、Promise.all()の中は同時処理されているので、それぞれの関数が同じタイミングで処理されています。結果は関数の順番どおりです。getIceCream()の結果はiceCreamで、以下同文。
awaitとthenは同じなので、以下の様な書き方もできます。
return Promise.all([
getIceCream(),
getFood(),
getDrink(),
]).then([ iceCream, food, drink ]) => ({ iceCream, food, drink });
もちろん、この処理は簡単なので同期処理する必要もないのですが、apiコールや大きいデータを呼ぶ時はとても役に立ちます。
Promiseのtry & catch
リアルなアプリでは、エラーハンドリングを必ずしなければいけないのと、その結果を表示させなければいけないので、try / catchと一緒にPromiseを使います。
const getAllFood = async () => {
try {
const [iceCream, food, drink] = await Promise.all([
getIceCream(),
getFood(),
getDrink(),
]);
const allFoods = {
iceCream,
food,
drink
};
return allFoods;
} catch (error) {
return Promise.reject(error);
}
};
getAllFood()
.then(allFoods => console.log(allFoods))
.catch(error => console.log(error));
try / catchの中で、Promiseの同期処理を行い、エラーが出た場合は、コールバックでキャッチしていて、必ず何かを返す様にしています。
ここに良記事があるのでよろしければ
https://dev.to/mrm8488/using-es6-array-destructing-with-promises-cco