1

jQuery を使用する Web アプリケーションに取り組んでいますが、テスト時に競合状態のように見えるものを取得しています。最善を尽くしても、どのように進めればよいかわかりません。

コードはGitHubにありますが、ここで奇妙な動作を要約します。

初期の AJAX リクエスト

AJAX 呼び出しと DOM の準備が必要なコードがいくつかあります。処理を高速化するために、$(document).ready() イベントが発生する前に AJAX 呼び出しを行っています。リンクされた JS ファイルでは、これは "init" 関数です。この関数は、AJAX 要求を設定する _build_site_select を呼び出します。完了すると、_on_site_list_success が呼び出されます。

$(document).ready() について

ready() に到達したら、AJAX と ready() イベントの両方を起動する必要がある呼び出しを行います。リンクされたコードでは、これは populate_site_select 呼び出しです。ready() が呼び出されたときに AJAX が完了していない可能性があるため、AJAX 操作が完了した後に設定した変数を確認し、setTimeout を使用して populate_site_select の呼び出しを遅らせます。変数 site_list_ready は、AJAX 呼び出しが完了すると設定され、実行前にサイト リストを完全に終了する必要がある関数でチェックインされます。

予想される動作と観察される動作

私が期待する動作は、_on_site_list_select のオブジェクト/連想配列が完全に設定された後にのみ populate_site_select が呼び出されることです。ただし、常にそうであるとは限りません。ときどき、populate_site_select に到達すると、配列に部分的にしかデータが取り込まれていないことがあります - 失敗するという点で一貫しているように見えます (私が期待する ~30 とは対照的に、常に配列内の同じ単一のエントリです)。

私が試したこと

また、setTimeout 呼び出しを _on_site_list_success 呼び出しに追加してみました。これにより、配列の人口が site_list_ready 変数の設定からさらに分離されます。ただし、これは問題を防ぐものではありません。

AJAX 呼び出しから返された JSON データが正しいことはわかっています (Chrome デバッガーで表示できます)。後で (ページの読み込みが完了した後に) サイト リスト変数の値を確認すると、適切に入力されています。

これは珍しいシナリオではないようで、バグが Chrome にあるとは信じがたいと思います (ただし、他のブラウザーでこれをテストしたことはありません)。私は何を間違っていますか?

4

1 に答える 1

2

以下のコードは試していませんが、jQuery のDeferredオブジェクトが役に立ちます。

var domReady, ajax;
domReady = jQuery.Deferred();

jQuery(function () {
    // on DOM ready
    domReady.resolve();
});

ajax = jQuery.ajax({
  url: '/path/to/file',
  type: 'GET',
  dataType: 'xml/html/script/json/jsonp'
});

jQuery.when(domready, ajax).then(doneCallbacks, failCallbacks);

基本的に、2 つの遅延オブジェクトがあります。1 つは DOM 準備完了状態を処理し、もう 1 つは AJAX 呼び出しを処理します。最初のオブジェクトを手動で管理し、DOM の準備ができたら解決します。2 つ目は、jQuery 自体によって自動的に管理されます ($.ajaxオブジェクトはDeferredオブジェクトであり、AJAX 呼び出しが成功すると解決されます)。

最後にjQuery.when()、遅延オブジェクトのステータスを監視し、両方が解決されると、doneCallbackが起動されます。2 つのオブジェクトのいずれかが拒否された場合、failCallbackが起動されます。

したがって、doneCallbacksは 2 つの Deferred オブジェクトが解決された後に呼び出される関数であり、DOM の準備が整い、AJAX 呼び出しが行われて成功します。

jQuery.when()およびオブジェクトのドキュメントを参照してくださいDeferred

于 2012-04-28T14:53:38.483 に答える