今回はPromiseについての備忘録です。
1:「Promise」とは?
・【非同期処理を、より簡単に書けるようにしたもの】です。
・非同期処理といえばコールバック関数がありますね。
そんなコールバック関数も「チェーン」により処理を繋げることができます。
⬇︎
//////コールバック関数の「チェーン」の例。
//⬇︎①sleep関数を定義する。
//引数にはcallbackに「コールバック関数function(val)」が渡ってくる。
//setTimeout内で「コールバック関数function(val)」が実行される。
function sleep(callback, val) {
setTimeout(function() {
console.log(val++); //コンソール結果 「0, 1, 2, 3,」と1秒ずつ値が表示される。
callback(val);
}, 1000);
}
//⬇︎②sleep関数を実行する。
//「sleep関数の中のコールバック関数(function(val)の中で【更にsleepを呼びます。】」
//これが【複数の非同期処理を順番に実行する、非同期処理のチェーン】です。
sleep(function(val) {
sleep(function(val) {
sleep(function(val) {
sleep(function(val) {
}, val);
}, val);
}, val);
}, 0);
⬇︎
❌ここで問題となるのはsleepの中で更にsleepを読み込むため、「多階層が深くなりコードの可読性が下がります。」
⬇︎
❌そのため「コールバック関数というのは、非同期のチェーンを繋げるために適した記述では無い」ことが分かります。
⬇︎
⭕️この問題を解決するために【Promiseという非同期処理のチェーン】を繋げるためのオブジェクトが導入されました。
2: 「Promiseの書き方」
・Promise構文
⬇︎
・new Promise➡︎「Promiseをインスタンス化」してあげます。
・.thenメソッド、.catchメソッド、.finallyメソッドを使って➡︎「非同期処理に対して制御を加えてあげることになります。」
////Promise構文
new Promise(function(resolve, reject)
//同期処理が実行される。
).then(
//非同期処理が実行される。
).catch(
//非同期処理が実行される。
).finally(
//非同期処理が実行される。
);
////⬇︎上記のPromise構文を参考にした具体例。
//多階層にならないのでPromiseは非同期処理のチェーンを処理するために適した記述です。
new Promise(function (resolve) {
resolve('hello');
}).then(function(data) {
console.log(data); //コンソール結果➡︎コールスタックが空っぽになった後に、’hello’が出力される。
})
.then(function(data) {
console.log(data); //コンソール結果は同じく’hello'で、しかも多階層にならない!Promiseは非同期処理のチェーンを処理するために適した記述方法!
})
.catch(function(data) (
console.log('エラーだよ'); //catchはエラー処理。
).finally(function(){
console.log('終了') //finallyで終了処理。
});
⬇
■new Promiseの引数として「function(resolve, reject)」を設定します。
・resolveが呼ばれた場合
解決処理が実行される。
「resolve」が呼ばれた場合には【.thenメソッドの中のコールバック関数function(data)が実行されることになり、引数dataにはresolveで渡した実引数'hello'などが渡ってきます。」
・rejectが呼ばれた場合
エラー処理が実行される。
「reject」というのは【Promiseのコールバック関数で、エラーが発生した時にPromiseに通知してあげるために使用する関数】です。
・引数function(data)
resolve(‘hello’)や、reject('bye')で渡した実引数’hello’や'bye'が渡ってきます。
■「then, catch, finally」の各解説。
・thenメソッド
resolveで条件に一致したら実行される。catchメソッドはスキップされて、finallyメソッドに処理が移ります。
・catchメソッド
rejectでエラー処理が実行される。.catchメソッドが完了したら、.finallyメソッドに処理が移ります。
・finallyメソッドが呼ばれた場合
thenメソッド、catchメソッドの後に呼ばれるfinallyメソッドは終了処理を記述していきます。
.finallyメソッドの中で使用するコールバック関数functionは、【(data)引数を取ることができません。
3: 「Promiseの書き方:2」
Promiseのおかげで非同期処理しやすくなったな〜と実感してきた所で、
①「throw new Error」でthenメソッドから➡︎catchのエラー処理を強制実行する。
②「setTimeoutを使った非同期処理の書き方」の紹介。
などの実装をしてみます。(少し見えにくいかもしれませんがご容赦ください…。)
////①「throw new Error」でthenメソッドから➡︎catchのエラー処理を強制実行する。
new Promise(function (resolve, reject) {
console.log('promise 開始');
resolve('hello'); //⬅︎resolveでthenを実行する。
//reject('bye');
})
.then(function (data) {
console.log('then①:' + data); //⬅︎コンソール結果:then①:hello
throw new Error(); //⬅ここでthrow new Errorを使うと「catchの処理が強制実行します。」
return data; //⬅return dataを設定すると「次の処理にdata(resolveやrejectの引数hello)を渡せる。
//throw new Error();をコメントアウトするとhelloを渡せる。
})
.then(function (data) {
//このthenメソッドは無視されcatchに処理が移る。
console.log('then②:' + data);
return data;
})
.catch(function (data) {
console.log('エラーcatch:' + data); //⬅︎コンソール結果:エラーcatch
})
.finally(function () {
console.log('finally'); //⬅︎最後にfinallyで終了。
});
console.log('global end 終了'); //同期的に処理されるので「コンソールのpromise開始のあとに出ます。」
////②「setTimeoutを使った非同期処理の書き方」の紹介。
new Promise(function (resolve, reject) {
console.log('promise 開始');
//⬇︎setTimeoutを実行。1秒後にresolveでthenメソッドを処理していく。
setTimeout(function () {
resolve('hello');
}, 1000);
//reject('bye');
})
.then(function (data) {
console.log('then①:' + data); //コンソール結果: then①:hello
return data;
})
.then(function (data) {
console.log('then②:' + data); //コンソール結果: then②:hello
return data;
})
.catch(function (data) {
//このcatchメソッドは今回はもちろん実行されない。
// console.log('catch:' + data);
})
.finally(function () {
console.log('finally'); //⬅︎最後にfinallyで終了。
});
console.log('global end 終了'); //同期的に処理されるので「コンソールのpromise開始のあとに出ます。」
⭕️Promiseのおかげで「コールバック関数などの非同期処理を、見やすく書けるようになります。」
4:「Promise」の備忘録でした
こうしてインプットとアウトプットを繰り返していると、記憶に定着して1歩ずつ進んでいるなと感じます。