XMLHttpRequest Synchronous mode not work in Firefox

D

David

Hello
I'm testing the XMLHttpRequest object in Firefox and IE. The code
below works well in IE and Firefox. It shows "1" when the string is a
number and "0" when not. The page aspxTest.aspx only write "0" or "1"
with a "response.write" method.
The problem that I have is when I try this example with Synchronous
mode. If I change the function sendNum with:

xmlhttp.open("GET",url,false);

In IE works well (show "0" or "1") but in Firefox don't show anything.
I have put an alert in "end" function before the condition of
xmlhttp.readyState but anything is writed. What's is wrong?

Thanks a lot


<html>
<head>
<script>
var xmlhttp;
function sendNum ()
{
try
{
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP")
}
catch (e)
{
try
{
xmlhttp=new ActiveXObject("Msxml2.XMLHTTP")
}
catch (E)
{
xmlhttp=false
}
}

if (!xmlhttp && typeof XMLHttpRequest!='undefined')
{
try
{
xmlhttp = new XMLHttpRequest();
}
catch (e)
{
xmlhttp=false
}
}

xmlhttp = new XMLHttpRequest();
var url = "http://localhost/Test/aspxTest.aspx?num=" +
document.forms['f'].elements['num'].value;
xmlhttp.open("GET",url,true);
xmlhttp.onreadystatechange = end;
xmlhttp.setRequestHeader('Accept','message/x-jl-formresult')
xmlhttp.send(null);
}

function end ()
{
//alert("end function");
if (xmlhttp.readyState == 4)
{
alert(xmlhttp.responseText);
}
}
</script>
</head>
<body>
<form id="f">
Number: <input type="text" width="100px" id="num">
<input type="button" value="is a number" onclick="sendNum()">
</form>
</body>
</html>
 
M

Martin Honnen

David said:
I'm testing the XMLHttpRequest object in Firefox and IE. The code
below works well in IE and Firefox. It shows "1" when the string is a
number and "0" when not. The page aspxTest.aspx only write "0" or "1"
with a "response.write" method.
The problem that I have is when I try this example with Synchronous
mode. If I change the function sendNum with:

xmlhttp.open("GET",url,false);

You shouldn't use the onreadystatechange event handler if you are using
a synchronous request, instead then you should do e.g.
xmlhttp = new XMLHttpRequest();
var url = "http://localhost/Test/aspxTest.aspx?num=" +
document.forms['f'].elements['num'].value;
xmlhttp.open("GET",url,true);
xmlhttp.setRequestHeader('Accept','message/x-jl-formresult')
xmlhttp.send(null);
if (xmlhttp.status == 200) {
// use xmlhttp.responseText or responseXML here
}
else {
// handle different response status here
}

that is simply place your code consuming the response after send(null),
as that method blocks.

But usually on the web you shouldn't use synchronous mode at all as it
blocks the browser and the user interface. For testing it might be fine
to start with synchronous requests but as you already know about
asynchronous requests and onreadystatechange simply use that.
 
D

Daniel Kabs

Martin said:
But usually on the web you shouldn't use synchronous mode at all as it
blocks the browser and the user interface. For testing it might be fine
to start with synchronous requests but as you already know about
asynchronous requests and onreadystatechange simply use that.

I did not know that XMLHttpRequest had a synchronous mode. Very interesting.

Indeed I think, synchronous mode has some advantages because JS's event
driven approach does not lend itself well to some problems. Synchronous
is fine, as long as you can impose a timeout. Can you do this with
XMLHttpRequest?

Cheers
Daniel Kabs
Germany
 
M

Martin Honnen

Daniel said:
Indeed I think, synchronous mode has some advantages because JS's event
driven approach does not lend itself well to some problems. Synchronous
is fine, as long as you can impose a timeout. Can you do this with
XMLHttpRequest?

As script in current browsers like Mozilla runs in the user interface
thread a synchronous request means that the user interface is blocked
while the request is being performed and while the response is being
received.
XMLHttpRequest in Mozilla and in Opera does not have a method to set
timeouts, neither has Msxml2.XMLHTTP used client side in IE.
The Msxml2.ServerXMLHTTP object to be used on the server (e.g. in ASP
pages) has a method to set timeouts:
<http://msdn.microsoft.com/library/d...n-us/xmlsdk/html/xmobjXMLDOMServerXMLHTTP.asp>
<http://msdn.microsoft.com/library/d.../en-us/xmlsdk/html/xmmthsetTimeoutsMethod.asp>
 
D

Daniel Kabs

Hello Martin,

this thread is close to expire on my news server. How can you answer a
posting to a more than two months old thread in just a couple of
minutes? :)

Martin said:
As script in current browsers like Mozilla runs in the user interface
thread a synchronous request means that the user interface is blocked
while the request is being performed and while the response is being
received.
XMLHttpRequest in Mozilla and in Opera does not have a method to set
timeouts, neither has Msxml2.XMLHTTP used client side in IE.

Thanks for pointing that out. So one has to *rely* on the fact, that the
server's response is swift. Not nice, but the alternative is an
asynchronous request, which is also not without ramifications.

Cheers
Daniel Kabs
Germany
 
J

Jim Ley

Hello Martin,

this thread is close to expire on my news server. How can you answer a
posting to a more than two months old thread in just a couple of
minutes? :)



Thanks for pointing that out. So one has to *rely* on the fact, that the
server's response is swift. Not nice, but the alternative is an
asynchronous request, which is also not without ramifications.

No, always use async, sync is very bad on anything with a UI.

Jim.
 
D

Daniel Kabs

Hello Jim,

I came across your pages while searching for help on some javascript
problems and I just wanted to say that I like your jibbering.com website.

Jim said:
No, always use async, sync is very bad on anything with a UI.

I've read that on your page, too. But asynchronous programming can be
awkward. Imagine you have several object, one object calls a method of
another object and so on. The last method invoked in this "cascade" is
supposed to load an image and return the image object. Now this can not
be accomplished in JS because the image is going to be loaded in an
async way and the method returns immediately. All the functions have to
return, the stack unwinds and the status is lost, if it is not saved
in e.g. callbacks using closures. And every method in this "cascade" has
to support callbacks, just because the last function is async. See the
sequence diagram in [2].

A solution could be to wrap the async functions with a "Synchronous
Wrapper Facade in Javascript" (if that is possible in JS, but I doubt
it). Please have a look at my corresponding question in [2].

Cheers
Daniel Kabs
Germany
 
J

Jim Ley

I've read that on your page, too. But asynchronous programming can be
awkward.

No more awkward than all the rest of javascript/html which relies on
it, it's all event based, I can't see how if you can cope with that
you'll have any more of a problem with this?

It's not awkward, it's just a different way of programming, and as you
have to use it for the rest, I fail to see the problem. The "load an
object, which loads an object, which loads an object which returns an
image" is simply not a pattern you should be using in webpages, I
don't think it's useful to try and create hacks and workarounds to fit
that pattern, just pick a more appropriate one.

Sync simply violates any user interface rules that the interface
cannot lock up. The big problem is that people test locally, or with
fast, reliable connections to their server, whereas the users will be
a long way away on unreliable connections, and they'll get very
different behavour.

Then there's the number of complete lock-up bugs when there are
multiple sync requests going on, it's simply not appropriate.

Jim
 
R

Richard Cornford

Daniel said:
Jim Ley wrote:

There are far too many factors influencing how swift a server's response
may be for relying on it being swift to be a good idea. And with
synchronous xmkhttp requests the browser is effectively dead until it
gets its response, or times out the request.

The ramifications are having to put more thought an work into the design
of the system. But background loading over HTTP was always going to add
a level of additional complexity, if that is more complexity that the
programmers responsible can cope with then they would be best advised to
give up background loading.
I've read that on your page, too. But asynchronous
programming can be awkward.

Awkwardness is going to be largely a matter of perception. Procedural
code doesn't lend itself to asynchronous operation but OO code shouldn't
be such a problem. In OO the 'state' should be a quality of the objects
not the stack.

Having spent the last few months working with precisely this problem my
conclusion is that it is best to design the entire client-side system to
be 'event' driven. That is; all interactions between (significant)
client-side objects are handled through 'events', where an object
defines a number of 'events' that are important in its behaviour
(triggered by internal state changes and/or state transitions) and other
objects that are interested register 'event listeners' with those
objects (thus reacting to state changes and transitions in the relevant
event generating objects).

So the asynchronous arrival of a response form a web service would
trigger an event, and fire registered event listeners, and the objects
that registered those listeners may themselves register event listeners
to carry out their response to the web service only when it was
appropriate in the rest of the system (such as following a 'modal dialog
closed' event, in the event that a modal dialog was open at the time).

Once the client-side event driven system has been formalise in the
architecture appropriately responding to asynchronous activity (from the
user or from remote servers) is not at all awkward.
Imagine you have several object, one object calls a method of
another object and so on. The last method invoked in this
"cascade" is supposed to load an image and return the image
object. Now this can not be accomplished in JS because the
image is going to be loaded in an async way and the method
returns immediately.

Right, there is no point designing a system to require the synchronous
loading of an image in an environment where you cannot synchronously
load an image.
All the functions have to return, the stack unwinds and
the status is lost, if it is not saved in e.g. callbacks
using closures. And every method in this "cascade" has to
support callbacks, just because the last function is async.

As I said, the state of an object should be a quality of that object,
the only information that the callback function should need to preserve
is which object instances are interested in the loading of the image,
and how they want to react to it (which method to call on them).
See the sequence diagram in [2].

I see no sequence diagram.
A solution could be to wrap the async functions with a
"Synchronous Wrapper Facade in Javascript" (if that is
possible in JS, but I doubt it).

If it were possible (and it isn't) it would be solving the wrong
problem.
Please have a look at my corresponding question in [2].

The literal answer to your corresponding question is no. The real answer
will only follow from identifying the real problem.

Richard.
 
D

Daniel Kabs

Hello!

Jim said:
It's not awkward, it's just a different way of programming, and as you
have to use it for the rest, I fail to see the problem. The "load an
object, which loads an object, which loads an object which returns an
image" is simply not a pattern you should be using in webpages, I
don't think it's useful to try and create hacks and workarounds to fit
that pattern, just pick a more appropriate one.

I'm sorry if you received the impression that I would implement "load"
requests by recursive object calls. That's not what I meant when I wrote
"one object calls another". And of course I do not want the UA/UI to
freeze. Maybe I was too unprecise.

The problem is not asynchronous programming per se. I've done that
before. The problem is that Javascript provides no means of waiting for
results, i.e. it's a completely async environment.

Thus (as I wrote before) if you have a method calling another method
calling another method doing something async, even the first
method/function has to provide for this async behaviour and pass a
closure as parameter to continue after the async call has finished and
triggers the event handler. I find this "awkward" because this prevents
to "abstract away" deeper levels of functionality as even the highest
abstraction level has to know about the async type of the underlying
levels. Or am I completely mistaken?

Cheers
Daniel
 
D

Daniel Kabs

Hello Richard,

thanks for sharing your ideas and the detailed description how a
completely event-driven system works.

Richard said:
Awkwardness is going to be largely a matter of perception. Procedural
code doesn't lend itself to asynchronous operation but OO code shouldn't
be such a problem. In OO the 'state' should be a quality of the objects
not the stack.

Yes, it's the feeling that makes one prefer a certain design. I would
not rule out procedural code for async operations. E.g. I imaging that
implementing a network protocol using a statemachine is an appropriate
approach. In OO code you would break up the case/switch statements and
"spread them around", delegate it to objects and their methods. Now the
objects keep their own state (and implement a statemachine). Is this
advantageous, I don't know.

Maybe it's just because I have a background in procedural programming.
So designing a completely event-driven system, where objects interact
sending async messages seems counter-intuitive because it lacks a main
flow of control.

I found the following example helpful:
In procedural programming you often have the control flow in a main
routine that calls other components only to do lower-level tasks. The
main routine can be long and complex but it gives the whole thing a
logical structure.

In an event-driven program you don't have that control flow in the main
routine. The main routine sends of messages and mainly consists of event
handlers. Not the main routine but the objects are now "in charge" and
not only sequentially, but also concurrently as messages and events may
happen any time. So the logical structure of the program is scattered
around and interactions among objects may be hard to understand.
Additionally, the use of ordinary linguistic constructs like loops,
stack allocated variables, ... is limited as these disappear accross
callbacks/messages.

Well, maybe one just has to get used to it :) I'd like to see a real
good example of an event-driven system with object interaction through
messages implemented using Javascript.
See the sequence diagram in [2].

I see no sequence diagram.

Because there is none :) I referred to the wrong footnote. See here for
the sequence diagramm instead:
<[email protected]>
http://groups.google.de/group/de.comp.lang.javascript/msg/d7dba787abae68d4


Cheers
Daniel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top