Javascriptの同期処理と非同期処理を✅

思いの外アルコリズム(アルコール+アルゴリズム)の実装に苦戦をしていて四六時中お酒の事しか考えられなくなった23期スバルです。

MDNやRailsガイドを見漁っていいメソッドや考え方がないかな〜と模索中です。

どうやら自己結合型関連付けが使えるのでは?と感じているので明日のブログでまとめたいと思います。

今回は「サーバーからデータを取得する」方法について学習していきます。

サーバーからデータを取得とはどういうこと?

webサーバーからHTTPレスポンスを取得すること。

同期して通信する方法と非同期で通信する方法に分かれる。

axiosやdevourを使ってサーバーにリクエストを投げることが多い。

同期処理

複数のタスクを実行する際に一つずつ順番にタスクが実行される方式のこと

どこかページの一部を書き換えたい場合、例えば新しい商品の一群を表示したり新しいページを読み込ませたりをする毎に、ページ全体を読み直さなければならないのが同期通信の難点である。

一部だけ、例えばいいね機能やデータをサーバーから取得する機能を実装したいのであれば、非同期通信が推奨される。

非同期通信Ajax

一つのタスクを実行中であっても他のタスクを実行できる実行方式のこと

  • Web ページから細かいデータ (HTMLXMLJSON やプレーンテキストのような) をリクエストし、それを必要な部分だけ表示する。
  • Promiseベースで通信される

Promiseとは

作成された時点では分からなくてもよい値へのプロキシーです。非同期のアクションの成功値または失敗理由にハンドラーを結びつけることができます。これにより、非同期メソッドは結果の値を返す代わりに、未来のある時点で値を提供するプロミスを返すことで、同期メソッドと同じように値を返すことができるようになります。

javascriptに順序を与えてくれるもの。javascriptは非同期言語なため、一つのタスクを実行中であっても他のタスクを実行できる実行方式となっている。

そのため、aをやった後にb、そしてcという風に同期処理をしてくれない。

そんな時に、a⇨b⇨cと順番をつけてくれるのがPromise

console.log("1番目");

// 1秒後に実行する処理
setTimeout(() => {
  console.log("2番目(1秒後に実行)");
}, 1000);

console.log("3番目");

理想は1番目2番目3番目と表示されることだが、下記のようになってしまう。

1番目
3番目
2番目(1秒後に実行)

Promiseで順序を与えると、下記のように期待通りの値が返ってくる。

console.log("1番目");

#Promiseを順序を与えたい処理の前につける
new Promise((resolve) => {
  #1秒後に実行する処理
  setTimeout(() => {
    console.log("2番目(1秒後に実行)");
    #無事処理が終わったことを伝える
    resolve();
  }, 1000);
}).then(() => {
  # 処理が無事終わったことを受けとって実行される処理
  console.log("3番目");
});

# expected output
1番目
2番目(1秒後に実行)
3番目

同期処理と非同期処理の違い

ページを丸ごと持ってくるのか、一部だけとってくるのかの違い。

axios

ブラウザやnode.js上で動くPromiseベースのHTTPクライアントです。jQueryで言うところのjQuery.ajaxであり、非同期にHTTP通信を行いたいときに容易に実装できます。

(https://www.willstyle.co.jp/blog/2751/)

Get通信

fetchAnalyzes({ commit }) {

    const responseAnalyze = axios
      .get('analyzes')

      .then((responseAnalyze) => {
        commit('setAnalyze', responseAnalyze.data);
      })
      .catch((err) => console.log(err.responseAnalyze));
  },

api/v1/analyzesに対してGET HTTPリクエストを送っている。analyzeコントローラーのindexアクションを通り、返ってきたレスポンスをresponseAnalyzeに格納していますね。

Post通信

async loginUser({ commit }, user) {
    try {
      const userResponse = await axios.post('sessions', user); //createアクション実行
      commit('setAuthUser', userResponse.data);
      return userResponse.data;
    } catch (err) {
      console.log(err);
      return null;
    }
  }

async/awaitは先に上げたPromiseをもっとみやすく書き換えたものになる。

tryとcatchと併用して書くことで、成功時と失敗時の挙動に分解することができる。

ちなみにこれは、vuexのactionsに書いたログイン機能実装のコードである。

まとめ

  • axiosを使ってサーバーからデータを取得することが一般的
  • axiosはPromiseベースの通信を行う。

サーバからのデータ取得 - ウェブ開発を学ぶ | MDN

【Ajax】axiosを使って簡単にHTTP通信 | Will Style Inc.|神戸にあるウェブ制作会社

非同期処理とは? 同期処理との違い、実装方法について解説 | システム運用ならアールワークスへ