メッセージ投稿で非同期通信を実装

## 非同期通信とは？
こんなのとか、
<img src ="https://qiita-image-store.s3.amazonaws.com/0/252963/c785174e-1b0e-7cac-b720-b8bd029a1289.gif" width=30%>



こんなのができる仕組みです。

<img src ="https://qiita-image-store.s3.amazonaws.com/0/252963/800f1a51-fa57-8322-da9a-3f2264bc2b31.gif" width=30%>

要は、↑のような**ページの更新なしで画面をスラスラ処理できる仕組み**を非同期通信と言います。

## どうしてできるのか

非同期通信の内容を理解するために、クライアント・サーバー通信の方式で対をなす同期通信との対比を書きます。


**同期通信**
>同期通信はデータ通信のリクエストを出してからレスポンスが来るまでほかの処理を行わずにレスポンスを待ち続ける

**非同期通信**
>非同期通信ではレスポンスを待っている間にほかの処理を行える。ほかの処理を行っている際に、レスポンスを受信すると受信処理を実行する。

一言でまとめると、**サーバーからのレスポンスを待たずにブラウザで操作できるようにしている**からです。

## Ajax
これを実現するのがAjaxというエンジンです。エンジンといってもJavaScriptとXMLというテキストデータの組み合わせです。
「Asynchronous JavaScript ＋ XML」という構成要素から成るエンジンなのですが、　これのおかげで非同期通信を実現しています。

参考：
http://wa3.i-3-i.info/word12672.html

## コメント投稿の非同期通信
実際のコメント投稿機能を作った際のソースを記載します。


```show.html.rb
## コメントを表示するviewファイル
<div class ="contents row">
  <div class="content_post" style="background-image: url(<%= @tweet.image %>);">
    <% if user_signed_in? && current_user.id == @tweet.user_id %>
      <div class="more">
        <span><%= image_tag 'arrow_top.png' %></span>
        <ul class="more_list">
          <li>
            <%= link_to '削除', "/tweets/#{@tweet.id}", method: :delete %>
          </li>
        </ul>
      </div>
    <% end %>
    <%= simple_format(@tweet.text) %>
    <span class="name">
      <a href="/users/<%= @tweet.user.id %>">
        <span>投稿者</span><%= @tweet.user.nickname %>
      </a>
    </span>
  </div>
  <div class="container">
    <% if current_user %>
      <%= form_tag("/tweets/#{@tweet.id}/comments", method: :post, id: "new_comment") do %>
        <textarea cols="30" name="text" placeholder="コメントする" rows="2" class ="textbox"></textarea>
        <input type="submit" value="SENT">
      <% end %>
    <% end %>
    <div class="comments">
      <h4>＜コメント一覧＞</h4>
      <% if @comments %>
        <% @comments.each do |comment| %>
          <p>
            <storng><%= link_to comment.user.nickname, "/users/#{comment.user_id}" %>：</strong>
            <%= comment.text %>
          </p>
        <% end %>
      <% end %>
    </div>
  </div>
</div>
```

```products/search.json.jbuilder
#↓ jbuilderを使って入力データをJSON形式で出力し、JavaScriptに渡す。
json.array! @products do |product|
  json.id product.id
  json.title product.title
  json.image product.image_url
  json.detail product.detail
end
```

```comments_controller.rb
class CommentsController < ApplicationController
  def create
    @comment = Comment.create(text: comment_params[:text], tweet_id: comment_params[:tweet_id], user_id: current_user.id)
#↓respond_toでリクエストされたフォーマットによって処理を分岐
    respond_to do |format|
      format.html{redirect_to tweet_path(params[:tweet_id])}
      format.json
    end
  end

  private
  def comment_params
    params.permit(:text, :tweet_id)
  end
end
```

```assets/javascripts/comment.js
// ↓コメントを出力する関数を定義
$(function(){
  function buildHTML(comment){
    var html = `<p>
                  <strong>
                    <a href = /users/${comment.user_id}>${comment.user_name}</a>:
                    </strong>
                    ${comment.text}
                    </p>`
    return html;
  }

// ↓送信ボタンクリック時にイベント発火
$("#new_comment").on("submit",function(e){
//↓e.preventDefaultで送信ボタンクリック時の通信を止める 
    e.preventDefault();
    console.log(this)
//　↓formDataでフォームの情報を取得
    var formData = new 
FormData(this);
// ↓非同期通信でコメントが保存されるようにする
    var url = $(this).attr("action")
    $.ajax({
      url:url,
      type:"POST",
      data:formData,
      dataType:"json",
      processData:false,
      contentType:false
    })
//↓ 非同期通信成功時に上で定義した関数を実行
    .done (function(data){
      var html = buildHTML(data);
      $(".comments").append(html)
      $(".textbox").val("")
    })
//↓エラー時の処理
    .fail(function(){
      alert("error");
    })
  })
})```
```

## 処理の流れ
全体の流れをざっくりまとめると、以下のようになります。
①viewからコメントを送信
②JS上でコメントの送信を中止、JSON形式への変更リクエスト
③Controllerがリクエスト別で処理を分岐（今回はJSON）
④jbuilderがデータをJSONに変換
⑤JSで表示を実行

![image.png](https://qiita-image-store.s3.amazonaws.com/0/252963/d879842c-9577-580c-3608-afb763cdb1f2.png)



## まとめ
非同期通信とは、**ページの更新なしで画面をスラスラ処理できる仕組み**である
非同期通信の仕組みとは、**サーバーからのレスポンスを待たずにブラウザで操作できるようにしていることである**
非同期通信を実現するものは、**Ajax**である
Ajaxを使うと、**JS上で表示の処理を柔軟に変えられる**