非推奨になったAjaxの同期通信によるブラウザの警告を対策する


ajax-async

Ajax同期通信について、かなり前から非推奨になっていることは皆さんご存知だと思いますが、最近古いコードを発見するまで忘れていた、と言うより意識していなかったので、この機会に過去へ振り返って概要と対策を記事にし思います。

同期・非同期とは?

詳しく説明するほど理解していないので、プログラマー目線で簡単に紹介したいと思います。

処理が完了するまで待つか待たないか

非同期通信

例えば、処理の実行タイミングを連続してコンソールに出力する以下のような処理があるとします。

$(function(){
  console.log("1. 処理開始");
  $.ajax({
    url: "/path/to/api",
    type: "get",
    dataType: "json",
    success: function(response) {
      console.log("2. Ajax処理終了");
    }
  });
  console.log("3. 処理終了");
});

プログラムは基本的に上から下に流れるので、1、2、3順番に表示されるはずですが、非同期通信の場合は、Ajaxで実行した結果が返ってくる前に次に処理に進みますので、結果はこのようになります。

> 1. 処理開始
> 3. 処理終了
> 2. Ajax処理終了

同期通信

ところが同期通信の場合は、Ajaxの処理が完了して結果が返ってくるまで待ちます。
前述のように警告が表示されますが、async: falseを使って同期通信にすることができます。

$(function(){
  console.log("1. 処理開始");
  $.ajax({
    url: "/path/to/api",
    type: "get",
    dataType: "json",
    async: false,
    success: function(response) {
      console.log("2. Ajax処理終了");
    }
  });
  console.log("3. 処理終了");
});

結果はこのようになります。

> 1. 処理開始
> 2. Ajax処理終了
> 3. 処理終了

処理が完了するまで次の処理に進まず待つ同期か、待たない非同期
つまり、処理の順番が違います。

もっと詳しく知りたい方はこちらをどうぞ

ajaxでjavascript関数から引数の戻り値を取得する方法の備忘録です。 ajaxのデフォルト設定は非同期となっており、引数の戻り値を受け取る前に処理がすすんでしまうため、処理された結果を関数より取得することができ …
[jQuery] ajaxの非同期処理と同期処理 - ChiyoPen - ChiyoPen

同期XMLHttpRequest廃止

同期通信は数年前からブラウザ開発コンソールに非推奨の警告が表示されるようになりました。
以下はFireFoxの記事のようですが、Chromeも同じです。

同期 XMLHttpRequest が廃止予定となりました
・・・
メインスレッド上での 同期リクエスト の使用、つまり ワーカー 以外での使用は、ユーザ体験に悪影響を及ぼすことから廃止予定とされ、開発者向けの Web コンソール に警告が出力されるようになりました。
引用:Wood-Roots:blog

Deferredを使った対策

最近、このことがきっかけでちょっとした事件が起こりました。
Prototype.js1.6系から1.7系にバージョンアップしたところ、同期通信が原因でプログラムが正常に動作しなかったのです。
この時は単純に同期から非同期に変更(asynchronous)するだけで良かったのですが、今後のために対策をメモしておきます。

以下の参考サイトがとても詳しかったので、ここでは敢えて書きません。

Deferredその1:何故をDeferred使うかの理由 さて、jQuery. ...
Deferredその1:何故をDeferred使うかの理由 - jQuery無双 - jQuery無双

ただ、同期通信の代わりなるとは考えられない。
結局のところ非同期通信にする限り処理は待ってくれないわけで、コールバックAjaxの中でやるか外でやるかの違いしかないように思う。
やっぱり次の処理を待つには、コールバック関数内に次の処理を入れるしかないのかな?
私がどうかしてる?
詳しい方、どうか誰か教えてください!


コメント

このブログの人気の投稿

Linuxでファイルの改行コードLF⇔CRLFを変換する方法

RHEL 7でスタティック(静的)ルートを追加する4つの方法

UTF-8のBOM付きとBOMなしを変換する方法(Linux)