LoginSignup
1
1

More than 1 year has passed since last update.

【JavaScript】非同期処理⑤ Promiseと並列処理

Posted at

はじめに

Udemyの【JS】ガチで学びたい人のためのJavaScriptメカニズムの講座の振り返りです。

前回の記事

目的

  • 非同期処理についての理解を深める

本題

1.並列処理

前提

function sleep(val) {
  return new Promise(function(resolve) {
    setTimeout(function() {
      console.log(val++);
      resolve(val);
       // このようにすることでループを重ねるごとに表示が遅れる
    }, val * 500);
  });
}

//Promiseチェーンしている
sleep(0).then(function(val) {
  return sleep(val);
}).then(function(val) {
  return sleep(val);
}).then(function(val) {
  return sleep(val);
})

例1

並列処理の書き方

function sleep(val) {
  return new Promise(function(resolve) {
    setTimeout(function() {
      console.log(val++);
      resolve(val);
    }, val * 500);
  });
}

// Promise.allとして()内に反復可能オブジェクトを入れる
// Promise.allが配列に格納されたPromiseのインスタンスが全て完了するまで次のthenメソッドを待つ
Promise.all([sleep(2), sleep(3), sleep(4)])
  .then(function(){
  // 2,3,4,endと出力
  // endが一番最後
  console.log("end");
});

thenメソッドの関数に引数を渡す

function sleep(val) {
  return new Promise(function(resolve) {
    setTimeout(function() {
      console.log(val++);
      resolve(val);
    }, val * 500);
  });
}

Promise.all([sleep(2), sleep(3), sleep(4)])
// 引数dataを渡す
  .then(function(data){
    // dataを出力すると配列となってresolveで渡された結果が帰ってくる
  console.log(data);
});

例2

Promiseチェーンの中でPromise.allを使う

function sleep(val) {
  return new Promise(function(resolve) {
    setTimeout(function() {
      console.log(val++);
      resolve(val);
    }, val * 500);
  });
}

Promise.all([sleep(2), sleep(3), sleep(4)])
  .then(function(data){
  console.log(data);
});
sleep(0).then(function(val) {
  // 上記のPromise.allの部分を下記のreturnのところで置換する
  // 次のthenメソッドも下記Promiseの処理が終わってから処理される
  return Promise.all([sleep(2), sleep(3), sleep(4)])
}).then(function(val) {
  // 出力すると先のPromisee.allの値が全て返ってくる
  console.log(val)
  return sleep(val);
}).then(function(val) {
  return sleep(val);
})

例3

Promise.raceで配列の中のどれか一つが呼ばれた時点でthenメソッドに処理が移行する

function sleep(val) {
  return new Promise(function(resolve) {
    setTimeout(function() {
      console.log(val++);
      resolve(val);
    }, val * 500);
  });
}

// コンソールに2,3,3,4と出力される
// sleep(2)が実行された時点で、次の処理に移行
// 2で引数に渡しているので,上記のval++で+1されるので3と出力される
Promise.race([sleep(2), sleep(3), sleep(4)])
  .then(function(data){
  console.log(data);
});

例4

Promise.allSettledの使い方

function sleep(val) {
  return new Promise(function(resolve) {
    setTimeout(function() {
      console.log(val++);
      resolve(val);
    }, val * 500);
  });
}


Promise.allSettled([sleep(2), sleep(3), sleep(4)])
  .then(function(data){
  console.log(data);
});

下記のように出力される

console.
(3) [{…}, {…}, {…}]
0: status: "fulfilled"
   value: 3
   [[Prototype]]: Object

1: status: "fulfilled"
   value: 4
   [[Prototype]]: Object

2: status: "fulfilled"
   value: 5
   [[Prototype]]: Object

length: 3
[[Prototype]]: Array(0)

fulfilledというのはresolveが呼ばれたタイミングのステータスを表している

もしrejectが呼ばれた場合はステータスがrejectedに変更される

function sleep(val) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      console.log(val++);
      // reject に変更
      reject(val);
    }, val * 500);
  });
}


Promise.all([sleep(2), sleep(3), sleep(4)])
  .then(function(data){
  console.log(data);
}).catch(function(e){
  // この場合catchの処理にエラーの表示が出る
  // allSettleではエラーが出力されない(ステータスで確認)  
  console.error(e);
});

allSettledは全ての処理を実行するが完了した非同期処理が成功したか失敗したかはわからない

allの場合はrejectが呼ばれた場合はcatchに処理が移る

function sleep(val) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      console.log(val++);
      // reject に変更
      reject(val);
    }, val * 500);
  });
}


Promise.all([sleep(2), sleep(3), sleep(4)])
  .then(function(data){
  console.log(data);
}).catch(function(e){
  // この場合catchの処理にエラーの表示が出る
  // allSettleではエラーが出力されない(ステータスで確認)  
  console.error(e);
});

今日はここまで!

参考にさせて頂いた記事

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1