[javascript]Promiseを使ってみました。

JavaScript

こんばんは。
nuxtjsでasync, awaitがたくさん付いているファイルを業務で見て、よくわからなかったので調べてみると
javascriptのpromiseが関係してるみたいだったので、まずはPromiseの挙動を確かめてみました。🧐

promise

調べてみると非同期処理を綺麗にかけて、コールバック地獄を回避できるらしいです。

使ってみた(サンプル)

インスタンス化

let process = new Promise(function(resolve, reject){
  console.log("start promise!!");                                                                                                                                            
});

// 結果:
// start promise!!

promiseをnewしてインスタンスを作成しています。
この時点で引数の無名関数が実行されます。

resolveの呼び出し

let process = new Promise(function(resolve, reject){
  console.log("start promise!!");
  resolve("codelike");
});

process.then(function(message){
  console.log("hoge1 " + message);
}).then(function(){
  console.log("hoge2");
}).then(function(){
  console.log("hoge3");
}).catch(function(){
  console.log("error!");
});

// 結果:
// start promise!!
// hoge1 codelike
// hoge2
// hoge3

後続処理はthenをメソッドチェーンで書いてresolveを呼びます。
resolveを書かない場合は後続処理は呼ばれません。
catchはrejectを呼び出すときに入ってきます。

rejectの呼び出し

let process = new Promise(function(resolve, reject){
  console.log("start promise!!");
  reject("codelike");
});

process.then(function(message){
  console.log("hoge1 " + message);
}).then(function(){
  console.log("hoge2");
}).then(function(){
  console.log("hoge3");
}).catch(function(message){
  console.log("error! " + message);                                                                                                                                                                         
});

// 結果:
// start promise!!
// error! codelike

上記のようにrejectを呼び出すと、catchの方に入ってきて、処理が行われます。(エラー処理ですね)
apiなどで、処理が成功したらresolveを使って、何らかの原因で失敗したらrejectを使うという使われ方をするんでしょうね。

後続処理の途中で判定したい場合は?

A処理(成功 or 失敗) => B処理 (成功 or 失敗)など後続処理のthenの中で判定したい場合はpromiseのインスタンスをreturnすればいいようです!

let process = new Promise(function(resolve, reject){
  console.log("start promise!!");
  setTimeout(function() { resolve("codelike") }, 2000);
});
console.log("test AAA");

process.then(function(message){
  console.log("hoge1 " + message);
}).then(function(){
  return new Promise(function(resolve) {
    setTimeout(function() {
      resolve("apple");
    }, 2000);
  });
}).then(function(message){
  console.log("hoge3 " + message);
}).catch(function(message){
  console.log("error! " + message);
});
console.log("test BBB");   

// 結果:
// start promise!!
// test AAA
// test BBB
// hoge1 codelike
// hoge3 apple

同期してないのがわかるように、setTimeoutを入れてみました。
最初のpromiseは2秒後に後続処理を行うようにしているので、処理が流れて、先に「test AAA」と「test BBB」が出てきていますね。
2秒後に「hoge1」にきて次の処理でpromiseでresoleveを返して、「hoge3」の後続処理に繋いでいます。

同じ処理をpromiseなしで書くと

console.log("start promise!!");
let error_flg1 = false;
let message = ""; 
setTimeout(function() { 
  message = "codelike";
  if(error_flg1 == false) {
    console.log("hoge1");

    setTimeout(function() {
      if(error_flg1 == false) {
        message = "apple"; 
        console.log("hoge3 " + message);
      } else {
        // catch
        console.log("error!");
      }   
    }, 2000);

  } else {
    // catch
    console.log("error!");
  }
}, 2000);
console.log("test AAA");
console.log("test BBB");

こんな感じにネストが深くなっていきます。
これがコールバック地獄なんでしょうね🤯
catchの概念もないので、毎回判定のロジックを入れるとかしないといけないですね。。

まとめ

promiseを実際に使って、挙動を確認してみましたが、使うとネストが深くならずに、
メソッドチェーンを使うことで、みやすくてわかりやすく処理が書けました。😄
async / awaitも確認してみます。

👋

JavaScriptプログラミング
プロフィール
yasuaki

福岡でフリーランスをやってます。
業界歴14年になりました、SESで働くことがほとんどです。
なんでもやってますが、Webが得意です。

このブログではプログラミング技術の内容を中心に商品レビューなどを書いています。
記事が参考になりましたら、共有やリンクなどいただけると幸いです。

yasuakiをフォローする
にほんブログ村 IT技術ブログへ
yasuakiをフォローする
コードライク

コメント

タイトルとURLをコピーしました