2011-03-18 31 views
17

在我的应用程序中,我正在使用Ext.Ajax.request加载我用eval执行的脚本。如何让JavaScript代码执行等待,直到带有脚本的AJAX请求被加载并执行为止?

的问题是,因为要花费时间,其之后执行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 
+4

把2.哪里3.是和放3.哪里2.是? – 2011-03-18 16:06:11

+0

AJAX请求完成后调用函数,并向用户显示“加载..”消息? – Kevin 2011-03-18 16:07:25

回答

12

阿贾克斯是异步的,这意味着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> 
3

因为Ajax调用是异步的,如果你想要执行的东西,取决于通过AJAX加载的数据,你将不得不在成功方法中执行它。将代码放在另一个方法中,然后在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> 
+1

是的,但要清楚你真的应该显示第三个控制台声明或者进入回调或进入你的新假功能。如图所示,对于不了解问题的人来说,它仍然相当混乱。 – 2011-03-18 20:55:26

1

你可以尝试使AJAX调用同步......当然,你必须停止使用Ext.Ajax的库,但它是值得的,如果你需要的代码的下一行之前阿贾克斯的结果。

这就是我的内网网页与我的数据库进行通信的方式。还有,我发现了一个挫折,因为你看不到任何页面更新,直到使用Javascript放弃控制权交还给页面,所以像一个状态栏,进度条或覆盖是不可能同步的Ajax(对于我的Firefox事实并非如此在某些情况下它甚至会在同步代码内更新)。

我使用这个 - 它有点本土和杂乱,但它在我的圈子里工作多年来一直是完美无暇的。只要创建一个新的AJAX(),设置URL中添加查询(名称/值对)根据需要,异步设置为false,当你调用从一个函数执行,它会阻止,直到阿贾克斯的回报。

或者,如果你想以异步方式使用它,只写了创建塔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

这可以通过创建一个XMLHttpRequest对象并调用open功能设置为false异步参数来实现。

var xmlhttp = new XMLHttpRequest(); 
xmlhttp.open("GET", "ajax_info.txt", false); 
var response = xmlhttp.responseText; 
相关问题