2016-11-13 5 views
1

おはようございます -

$.ajaxコールが終了したかどうかを確認するよく知られた方法はありますか?

- INSTANCE FOR -

のは、私が(非同期層群など).geojsonファイルからリーフレットの多数のポリゴンにロードするために$.ajaxコールを使用していましょう。通常の状況下では、これはほぼ即座に発生しますが、ユーザーは今度は大規模なジョブをロードすることを選択しました。ユーザーは、ポリゴンのセットがロードされているとみなし、このグループのレイヤーで早すぎる何かをしようとします。何も起こらない(レイヤーグループは実際にブラウザーには存在しません)。

私の直感(私はウェブ開発の初心者です)は、依存アルゴリズムがチェックするように設定された何らかの種類のグローバルフラグを持つことです。レイヤーをロードする前にフラグを設定して、$.ajaxコールの.done({})セクションの他の値に変更します。

- UPDATE -

私は、ユーザーが要求を再試行するかどうかを選択し、また、再試行する前に要求をいくつかの時間を待つように、ブラウザを強制的にできるようにするコードを作り直しました。

しかし、この問題はChromeで発生しているようです。 Firefoxは、終了するとすぐに$ .ajax.alwaysコールバックを処理できるように見えます(つまり、$ .ajax.alwaysコールバックはJavaScriptの通常の流れを妨害します)。

Chromeは$ .ajax.alwaysコールバックをブロックして表示され、他のすべてのjavascriptの実行が完了した後でのみ(割り込みなし)実行されます。

この特定の質問は、ループ内からのユーザー入力を自動化するデバッグケースに起因しています。現在のプロセスが完了するまでChromeが$ .ajax.alwaysコールバックを呼び出さないため、プロセスは完了しました。

コード例:

procBox = []; // Global scope, stands for Process Box 

function loadPolygons() { 
    procBox["loadPolygons"] = "running"; 

    $.ajax({ 
     // ajax things here 

    }).done(function() { 
     procBox["loadPolygons"] = "done"; 
    }).fail(function() { 
     // failure stuff here 
    }); 
} 

function dependentFunction() { 
    if procBox["loadPolygons"] === "done") { 
     // The meat of the function (dependentFunction things here) 

    } else { 
     // Backup case that allows the browser to retry the request 
     /* -- 
     * If this fires, the server is still trying to process the 
     * ajax request. The user will be prompted to retry the request, 
     * and upon agreement, the function will be called again after 
     * 1 second passes. 
     */ 

     var msg = "Oops! It looks like we're still fetching your " 
       + "polygons from the server. Press OK to retry."; 

     if (confirm(msg)) { 
      setTimeout(dependentFunction, 1000); 
     } 
    } 
} 

このアプローチは、Firefoxでうまく動作するようです - alert()は、JavaScriptの実行を停止し、それを.done({})コールバックが発生するために機会を与えてくれます。しかし何らかの理由でwhileループで.done({})コールバックがChromeで完了することはありません。

フラグやasync: falseを使用するよりも優れた方法は誰にも分かりますか?
回答と知識がありがとう!

+0

JavaScriptを無期限にブロックしないでください。タイムアウトまたは間隔を使用します。 – tkausl

+0

「約束」を読む。もう少し周りを頭で囲む必要があります。 – zero298

+0

あなたは '。always(...) 'を探しているかもしれません。 'try/catch'の' finnaly'のようですが、jqueryの 'done/fail'のため – notgiorgi

答えて

0

行うには数多くの方法があります。 は、すでにあなたはjQueryのを使用しているため、カスタムイベントhttps://learn.jquery.com/events/introduction-to-custom-events/を使用することができます を使用することができますsugegsted:

$(document).on("myajax:done", function(){ dependentFunction();}) 
$.ajax({...}).done(function(){ 
    $(document).trigger("myajax:done") 
}); 

、あるいはグローバルAJAXイベント https://api.jquery.com/category/ajax/global-ajax-event-handlers/

が、本当に何かをしない理由を考えてください

procBox = {onLoadPolygons:dependentFunction}; // Global scope 

function loadPolygons() { 
    $.ajax({ 
     // ajax things here 

    }).done(function() { 
     procBox["onLoadPolygons"](); 
    }).fail(function() { 
     // failure stuff here 
    }); 
} 

function dependentFunction() { 
     alert("Please wait for the polygons to load"); 
    dependentFunctionThings(); 

} 
function dependentFunctionThings(){ 
    // Do dependent function things... 
} 

UPD: あなたは構造上ensist、まだ阻止する機能にチェック

function dependentFunction() { 
    var h = setInterval(function() { 
     if (procBox["loadPolygons"] == "done") { 
      clearInterval(h); 
      // Do dependent function things... 
     } 
    }, 100); 
} 

または約束(http://caniuse.com/#feat=promises)にそれをラップを実行するための 使用のsetIntervalを使用したい場合は

function dependentFunction() { 
    (new Promise(function(resolve) { 
     var h = setInterval(function(){ 
     if (procBox["loadPolygons"] == "done") { 
      clearInterval(h);resolve(); 
     } 

     }, 100); 
    })).then(function(){ 
     // Do dependent function things... 
    }); 
} 

しかし、私はまだあなたの構造に何か間違っていると信じています。

+0

私はここで何か不足していると思います。コードはすでにFirefox上でうまく動作しています。 ユーザーがデータを再度編集しようとする前に、非同期アルゴリズムが完了したかどうかを確認するために、一時的にjavascriptを一時停止する必要があります。 ($ .ajaxが完了した後に関数が自動的に呼び出されることは望ましくありません。ユーザーが 'dependentFunction()'を呼び出したときにまだ処理されていないことを確認したいだけです。) –

+0

@Dylan、私はあなたの "dependentFunction"がどこでどのように呼び出されたのか分かりませんが、Ffで動作するのであれば驚きますが、無限ループを実行するとすぐにCPUをシャックする必要があります。 setTimeout(()=> {if(ajaxEnd == 1)doYourThings}、100)、あなたの "while"を "if"に置き換える必要があります。 – 2oppin

+0

alert()は、firefoxでjavascriptの実行を停止します。コールバックはまだ舞台裏で発しています。 10回のうち9回、$ .ajaxが完了してからアラート()で[ok]をクリックすると、1回目または2回目の試行でループが終了します。 しかし、これと同じアプローチはクロームでは機能しません(このアプローチでは根本的に何かが間違っていると私を信じています)。私はsetTimeout()関数でラップをチェックアウトしましたが、これはここからうまくいくようですが、まだ実装されていません。 –

-1

文書から:

.ajaxComplete() 

Ajaxリクエストが完了すると、jQueryによってajaxCompleteイベントがトリガーされます。 .ajaxComplete()メソッドで登録されているすべてのハンドラがこの時点で実行されます。

http://api.jquery.com/ajaxcomplete/

+0

興味深い - 私は次のようだと思います。 $ .ajaxが完了した後に起動される関数呼び出しのキューを作成できますか? これは、ユーザーがボタンをクリックしたときに 'dependentFunction'が呼び出されたときに、$ .ajax関数がまだ処理中である(procBox []フラグで)かどうかを調べる方法を見つけることです。 –

+0

実際、ajaxSuccess()は、HTTP 200応答でajax要求が行われたときにだけ呼び出されるため、おそらく良いでしょう。 ajaxComplete()は、ajaxリクエストが終了すると常に実行されます。とにかく、ポストajax関数を.ajaxComplete()/ .ajaxSuccess()関数に置き、それを使って遊んでください。 Jqueryのドキュメントとサンプルはかなり明白です。 – Kyobul

+0

Ajaxリクエストが完了するとすぐに何かが起きることはあまりありません。完了したことを確認するだけで済みます。それはまったくFirefoxでうまく動作します! (上記のトピックを更新して、Chromeでこれを実行すると間違っていると思われるものを説明します。おそらく、私が約束していないものがあります) –

関連する問題