web-dev-qa-db-ja.com

AJAXスクリプトを含むリクエストが読み込まれて実行されるまで、JavaScriptコードの実行を待機させるにはどうすればよいですか?

私のアプリケーションでは、Ext.Ajax.requestは、evalで実行するスクリプトをロードします。

問題は、AJAXリクエストの完了に時間がかかるため、AJAXを介してロードされたスクリプトにある変数を必要とする後で実行されるコードです。この例では、 AJAXの後のJavaScriptの実行がAJAX呼び出しのスクリプトがロードされ、処刑?

testEvalIssue_script.htm:

<script type="text/javascript">
    console.log('2. inside the ajax-loaded script');
</script>

main.htm:

<html>
    <head>
        <script type="text/javascript" src="ext/adapter/ext/ext-base.js"></script>
        <script type="text/javascript" src="ext/ext-all-debug.js"></script>
        <script type="text/javascript">
            function loadViewViaAjax(url) {
                Ext.Ajax.request({
                    url: url,
                    success: function(objServerResponse) {
                        var responseText = objServerResponse.responseText;
                        var scripts, scriptsFinder=/<script[^>]*>([\s\S]+)<\/script>/gi;
                        while(scripts=scriptsFinder.exec(responseText)) {
                            eval.call(window,scripts[1]);
                        }
                    }
                });
            }

            console.log('1. before loading ajax script');
            loadViewViaAjax('testEvalIssue_script.htm');
            console.log('3. after loading ajax script');
        </script>
    </head>
    <body>

    </body>

</html>

出力:

1. before loading ajax script
3. after loading ajax script
2. inside the ajax-loaded script

次のようにして、出力を正しい順序にするにはどうすればよいですか?

1. before loading ajax script
2. inside the ajax-loaded script
3. after loading ajax script
17
Edward Tanguay

Ajaxは非同期です。つまり、ajax呼び出しはディスパッチされますが、コードは停止することなく、以前と同じように実行し続けます。 Ajaxは、応答が受信されるまで実行を停止/一時停止しません。追加のコールバック関数などを追加する必要があります。

<html>
    <head>
        <script type="text/javascript" src="ext/adapter/ext/ext-base.js"></script>
        <script type="text/javascript" src="ext/ext-all-debug.js"></script>
        <script type="text/javascript">
            function loadViewViaAjax(url, callback) {
                Ext.Ajax.request({
                    url: url,
                    success: function(objServerResponse) {
                        var responseText = objServerResponse.responseText;
                        var scripts, scriptsFinder=/<script[^>]*>([\s\S]+)<\/script>/gi;
                        while(scripts=scriptsFinder.exec(responseText)) {
                            eval.call(window,scripts[1]);
                        }
                        callback.call();
                    }
                });
            }

            console.log('1. before loading ajax script');
            var afterAjax = function(){
                console.log('3. after loading ajax script');
            }
            loadViewViaAjax('testEvalIssue_script.htm', afterAjax);
        </script>
    </head>
    <body>

    </body>

</html>
12
ChrisR

Ajax呼び出しは非同期であるため、ajaxを介してロードされたデータに依存するものを実行したい場合は、successメソッドで実行する必要があります。コードを別のメソッドに配置し、evalステートメントの後にそのメソッドを呼び出します。

<script type="text/javascript">
            function doSomeAmazingThings() {
                // amazing things go here
            }

            function loadViewViaAjax(url) {
                Ext.Ajax.request({
                    url: url,
                    success: function(objServerResponse) {
                        var responseText = objServerResponse.responseText;
                        var scripts, scriptsFinder=/<script[^>]*>([\s\S]+)<\/script>/gi;
                        while(scripts=scriptsFinder.exec(responseText)) {
                            eval.call(window,scripts[1]);
                        }
                        doSomeAmazingThings(); 
                        console.log('3. after loading ajax script');
                    }
                });
            }

            console.log('1. before loading ajax script');
            loadViewViaAjax('testEvalIssue_script.htm');
        </script>
3
Robby Pond

これは、XMLHttpRequestオブジェクトを作成し、asyncパラメータをfalseに設定して open 関数を呼び出すことで実現できます。

var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "ajax_info.txt", false);
var response = xmlhttp.responseText;
1
Mahmood Khan

AJAX呼び出しを同期させてみてください...もちろんExt.Ajaxライブラリの使用を停止する必要がありますが、次のコード行の前にajaxの結果が必要な場合は価値があります。

これが私のイントラネットページが私のデータベースと通信する方法です。私が発見した後退があります。JavaScriptが制御をページに戻すまでページの更新を表示できないため、ステータスバー、進行状況バー、オーバーレイなどは同期Ajaxでは不可能です(私のFirefoxには当てはまりません) 、状況によっては同期コード内でも更新されます)。

私はこれを使用しています-少し自家製で乱雑ですが、私のサークルでは何年も問題なく動作しました。新しいAJAX()を作成し、URLを設定し、必要に応じてクエリ(名前と値のペア)を追加し、非同期をfalseに設定して、関数からExecuteを呼び出すと、Ajaxが戻るまでブロックします。

または、非同期で使用したい場合は、作成した「AJAXオブジェクト)の新しい "onready"関数を記述し、非同期をtrueに変更します。

私は何年も前にこれを書いたので、それは最も卑劣ではなく、異なる方法で行う方法がありますが、それは入門書として機能し、別のライブラリーに依存することなく、好きなように調整できます。

function AJAX(){

//Declarations
    var thisExt=this; //To be referenced by events

//Initialize Properties
    thisExt.URL="";
    thisExt.Query="";
    thisExt.Method="GET";
    thisExt.Asynchronous=true;
    thisExt.Encoding="application/x-www-form-urlencoded";
    thisExt.PostData="";

// Provide the XMLHttpRequest class for IE 5.x-6.x:
// Other browsers (including IE 7.x-8.x) ignore this
//   when XMLHttpRequest is predefined
if (typeof XMLHttpRequest == "undefined") {
    try { 
        thisExt.XMLHTTP = new ActiveXObject("Msxml2.XMLHTTP.6.0"); 
    }
    catch (e1) {
        try { thisExt.XMLHTTP = new ActiveXObject("Msxml2.XMLHTTP.3.0"); }
        catch (e2) {
            try { thisExt.XMLHTTP = new ActiveXObject("Msxml2.XMLHTTP"); }
            catch (e3) {
                try { thisExt.XMLHTTP = new ActiveXObject("Microsoft.XMLHTTP"); }
                catch (e4) {
                    throw new Error("This browser does not support XMLHttpRequest.");
                }
            }
        }
    }
} else {
    thisExt.XMLHTTP = new XMLHttpRequest();
}


//Methods
    thisExt.XMLHTTP.onreadystatechange = function(){
        if(thisExt.XMLHTTP.readyState==4){
            window.status="";
            thisExt.onready(thisExt);//Passes thisExt so that the callback will have assess to the entire object, not just the returned text.
        }else{
            window.status=thisExt.XMLHTTP.readyState;//Just for debugging
        }
    }
    thisExt.addQuery=function(name,value){
        if(thisExt.Query!=""){
            thisExt.Query+="&"
        }
        thisExt.Query+=encodeURIComponent(name)+"="+encodeURIComponent(value)
    }

//Not really necessary, you could just say AjaxObj.URL="bla bla"
    thisExt.setURL=function(URL){
        thisExt.URL=URL;
    }
//Not really necessary, you could just say AjaxObj.Query="bla bla"
    thisExt.setQuery=function(Query){
        thisExt.Query=Query;
    }
//Not really necessary, you could just say AjaxObj.Method="bla bla"
    thisExt.setMethod=function(Method){
        thisExt.Method=Method;
    }
//Not really necessary, you could just say AjaxObj.Encoding="bla bla"
    thisExt.setEncoding=function(Encoding){
        thisExt.Encoding=Encoding;
    }
//Not really necessary, you could just say AjaxObj.PostData="bla bla"
    thisExt.setPostData=function(PostData){
        thisExt.PostData=PostData;
    }

    thisExt.Execute=function(){
        if(thisExt.URL==""){
            alert("AJAX.URL cannot be null.")
            return;
        }
        var URL2=thisExt.URL;
        if(thisExt.Query!=""){
            URL2=URL2+"?"+thisExt.Query;

        }
        if(thisExt.Method=="POST"){
            //this.XMLHTTP.setRequestHeader("Content-Type",this.Encoding);
            thisExt.XMLHTTP.open("POST", URL2, thisExt.Asynchronous);
            thisExt.XMLHTTP.send(thisExt.PostData);
        } else {
            thisExt.XMLHTTP.open("GET", URL2, thisExt.Asynchronous);
            thisExt.XMLHTTP.send(null);
        }
    }

//Events & callbacks
    thisExt.onready=function(){}
}
1
alfadog67