Ajaxの同期通信について、かなり前から非推奨になっていることは皆さんご存知だと思いますが、最近古いコードを発見するまで忘れていた、と言うより意識していなかったので、この機会に過去へ振り返って概要と対策を記事にし思います。
同期・非同期とは?
詳しく説明するほど理解していないので、プログラマー目線で簡単に紹介したいと思います。
簡単に言うと、処理が完了するまで待つか待たないか、です。
非同期通信=待たない
同期通信=待つ
となります。
非同期通信
例えば、処理の実行タイミングを連続してコンソールに出力する以下のような処理があるとします。
1 2 3 4 5 6 7 8 9 10 11 12 |
$(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 2 3 |
> 1. 処理開始 > 3. 処理終了 > 2. Ajax処理終了 |
同期通信
ところが同期通信の場合は、Ajaxの処理が完了して結果が返ってくるまで待ちます。
前述のように警告が表示されますが、[async: false]を使って同期通信にすることができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$(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 3 |
> 1. 処理開始 > 2. Ajax処理終了 > 3. 処理終了 |
処理が完了するまで次の処理に進まず待つ同期か、待たない非同期。
つまり、処理の順番が違います。もっと詳しく知りたい方はこちらをどうぞ
同期XMLHttpRequest廃止
同期通信は数年前からブラウザの開発コンソールに非推奨の警告が表示されるようになりました。
以下はFireFoxの記事のようですが、Chromeも同じです。
同期 XMLHttpRequest が廃止予定となりました
引用:Wood-Roots:blog
・・・
メインスレッド上での 同期リクエスト の使用、つまり ワーカー 以外での使用は、ユーザ体験に悪影響を及ぼすことから廃止予定とされ、開発者向けの Web コンソール に警告が出力されるようになりました。
Deferredを使った対策
最近、このことがきっかけでちょっとした事件が起こりました。
Prototype.jsを1.6系から1.7系にバージョンアップしたところ、同期通信が原因でプログラムが正常に動作しなかったのです。
この時は単純に同期から非同期に変更(asynchronous)するだけで良かったのですが、今後のために対策をメモしておきます。
以下の参考サイトがとても詳しかったので、ここでは敢えて書きません。
ただ、同期通信の代わりなるとは考えられない。
結局のところ非同期通信にする限り処理は待ってくれないわけで、コールバックをAjaxの中でやるか外でやるかの違いしかないように思う。
やっぱり次の処理を待つには、コールバック関数内に次の処理を入れるしかないのかな?
私がどうかしてる?
詳しい方、どうか誰か教えてください!
コメント