Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get make JavaScript code execution to wait until an AJAX request with script is loaded and executed?

In my application, I am using Ext.Ajax.request to load scripts which I execute with eval.

The problem is that since it takes time for the AJAX request to complete, code that is executed afterward which needs variables which are in the script loaded in via AJAX. In this example, I show how this is the case. How can I change this code so that the execution of the JavaScript after the AJAX waits until the script in the AJAX call has been loaded and executed?

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>

output:

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

How can I get the output to be in the correct order, like this:

1. before loading ajax script
2. inside the ajax-loaded script
3. after loading ajax script
like image 645
Edward Tanguay Avatar asked Mar 18 '11 16:03

Edward Tanguay


People also ask

Is there any way to wait for AJAX response and halt execution?

Cut and paste whatever code you need to execute in the callback function passed to success . Some good answer is already provided.

How do I get AJAX response time?

The most simple method would be to add var ajaxTime= new Date(). getTime(); before the Ajax call and in the done get the current time to calculate how long the Ajax call took to make. var ajaxTime= new Date(). getTime(); $.

What happens when JavaScript makes an AJAX request in a browser?

When you make an AJAX request, your browser sends an HTTP request to a given address. The server on the other end of the request responds, and returns the data to your browser. This is the same thing that happens when you navigate to a new web page.


2 Answers

Ajax is asynchronous, that means that the ajax call is dispatched but your code keeps on running as happy as before without stopping. Ajax doesn't stop/pause execution until a response is received. You'll have to add an extra callback function or something like that.

<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>
like image 98
ChrisR Avatar answered Oct 11 '22 05:10

ChrisR


Since the ajax call is asynchronous, if you want to execute something that depends on data loaded via ajax, you will have to execute it in the success method. Put the code in another method, and then call that method after the eval statements.

<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>
like image 33
Robby Pond Avatar answered Oct 11 '22 07:10

Robby Pond