最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Script only works while alert box is in the script - Stack Overflow

programmeradmin0浏览0评论

If I take the alert call out of the following script firebug says that results is undefined?`

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" ".dtd">

<html>
    <head>
        <title>Inventory Management</title>
        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
        <title>Untitled Document</title>
        <script src="json.js" type="text/javascript"></script>
        <script src="prototype.js" type="text/javascript"></script>
    </head>
    <body>
        <div id="content">
            <div id="header">   
            </div>

            <script type="text/javascript">
                var xhr;
                var results=getPlants(xhr,results);
                var plants=[];

                function getPlants(xhr,results){
                    try {
                        xhr=new XMLHttpRequest();   
                    }catch(microsoft){
                        try{
                            xhr=new ActiveXObject("Msxml2.XMLHTTP");                
                        }catch(othermicrosoft){
                            try{
                                xhr = new ActiveXObject("Microsoft.XMLHTTP");               
                            }catch(failed){
                                xhr=false;
                                alert("ajax not supported");
                            }
                        }               
                    }

                    xhr.onreadystatechange= function () {
                        if(xhr.readyState==4 && xhr.status==200) {
                            results = xhr.responseText;                     
                        }
                    }

                    xhr.open("GET","db_interactions.php",true);     
                    xhr.send(null);
                    alert("sent");
                    return results;
                }

                plants.inv=[];
                plants.split = results.split("~");

                for (var x=0;x<=plants.split.length-2;x++){
                    plants.inv[x]=plants.split[x].evalJSON();
                }

                document.write(plants.inv[1].scientific_name);
            </script>
        </div>
    </body>
</html>

If I take the alert call out of the following script firebug says that results is undefined?`

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3/TR/html4/strict.dtd">

<html>
    <head>
        <title>Inventory Management</title>
        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
        <title>Untitled Document</title>
        <script src="json.js" type="text/javascript"></script>
        <script src="prototype.js" type="text/javascript"></script>
    </head>
    <body>
        <div id="content">
            <div id="header">   
            </div>

            <script type="text/javascript">
                var xhr;
                var results=getPlants(xhr,results);
                var plants=[];

                function getPlants(xhr,results){
                    try {
                        xhr=new XMLHttpRequest();   
                    }catch(microsoft){
                        try{
                            xhr=new ActiveXObject("Msxml2.XMLHTTP");                
                        }catch(othermicrosoft){
                            try{
                                xhr = new ActiveXObject("Microsoft.XMLHTTP");               
                            }catch(failed){
                                xhr=false;
                                alert("ajax not supported");
                            }
                        }               
                    }

                    xhr.onreadystatechange= function () {
                        if(xhr.readyState==4 && xhr.status==200) {
                            results = xhr.responseText;                     
                        }
                    }

                    xhr.open("GET","db_interactions.php",true);     
                    xhr.send(null);
                    alert("sent");
                    return results;
                }

                plants.inv=[];
                plants.split = results.split("~");

                for (var x=0;x<=plants.split.length-2;x++){
                    plants.inv[x]=plants.split[x].evalJSON();
                }

                document.write(plants.inv[1].scientific_name);
            </script>
        </div>
    </body>
</html>
Share Improve this question edited Jan 26, 2010 at 21:31 Josh Mein 28.7k15 gold badges78 silver badges88 bronze badges asked Jan 26, 2010 at 21:12 Daquan HallDaquan Hall 372 bronze badges 4
  • 1 I think you need to reformat, for easier reading by SO users. – sberry Commented Jan 26, 2010 at 21:14
  • 1 A few observations: don't use exceptions for flow control - they're very slow and makes code hard to read. Also, don't declare js functions in the middle of your markup; put them in the head or after the body. And reformat your code so we can read it, please. – 3Dave Commented Jan 26, 2010 at 21:16
  • And you may want to use one of the frameworks to take care of the browser-specific AJAX stuff. I thinkg you could reduce your script's volume by 50% by using JQuery or Prototype. (It's entirely optional and not really necessary. It just makes life easier.) – Pekka Commented Jan 26, 2010 at 21:18
  • This has been asked before. It's a mon problem. Search before you ask, please. stackoverflow./questions/1267454/… – Josh Stodola Commented Jan 26, 2010 at 21:37
Add a ment  | 

5 Answers 5

Reset to default 8

The reason it's not working is because the XmlHttpRequest is asynchronous. What this means is that you cannot do return results;

Here's a timeline, with your alert box:

  1. Create XmlHttpRequest
  2. Send it
  3. Alert box pops up and sits there for a while
  4. XmlHttpRequest result es back and sets the results variable in your onreadystatechange function
  5. You click OK on the alert box
  6. the function returns (the return results line)
  7. Other code runs and does things with the results variable.

Here's the timeline without the alert box:

  1. Create XmlHttpRequest
  2. Send it
  3. the function returns (the return results line)
  4. Other code runs and does things with the results variable. This fails because it hasn't been set yet
  5. XmlHttpRequest result es back and sets the results variable in your onreadystatechange function

Instead you have to put the plants code (splitting, etc) in the onreadystatechange callback, or put it in it's own function, and call that function from the onreadystatechange

You should modify the plants variable in the callback function assigned to the onreadystatechange property.

xhr.onreadystatechange = function(){
    if(xhr.readyState==4 && xhr.status==200) {
        results = xhr.responseText;
        // Populate the "plants" variable here, then call a function
        // that does something with the plants variable.
    }
}

For more information: https://developer.mozilla/en/AJAX/Getting_Started

When you call

xhr.open("GET","db_interactions.php",true);

you are telling the XMLHttpRequest to operate asynchronously. You are telling it to go off and do its work, calling the callback function at some unspecified time in the future, when the request has been fully processed. Change that true to false, and it will work as you expect. On the other hand, that function might hang indefinitely in the event of a network slowdown, etc., so caveat programmor.

The callback function that sets the 'results' variable is asynchronous -- meaning that it will likely get set after the return statement, unless there's something to delay the return statement (e.g. an alert() call).

XMLHttpRequest.send() is asynchronous. Without the alert the function runs faster than the ajax call and results is never initialized. You can fix this by changing the true in your open call to false to make it synchronous or set your global variable in your inline function

发布评论

评论列表(0)

  1. 暂无评论