Asynchronous programming in the browser



 How it’s done and why it doesn’t work

Complicated and long running functions have the unpleasant characteristic,
that during their execution all the other activities are standing still. In
particular really long running functions represent a genuine problem and
therefore both browsers the Microsoft Internet Explorer and Firefox are
offering the possibility of a brutal termination of execution.
The way out of this dilemma is possible when using a parallel execution of the
calculation of the factors and the handling of all user interface events like
keystrokes.
In the Browser and with the assistance of JavaScript there is only a very much
limited way of parallel execution with the assistance of a timer and events
possible. However the problems and the realizations of such parallel
algorithms must be suitable for this. When a JavaScript function runs then the
Events from the user inputs are no longer directly processed and the
application appears blocked again.
Splitting a long running task into multiple shorter tasks and why it doesn’t help
Implementing this idea in a browser can be done in the following approach:
With every keystroke a timeout (_timer) is registered to trigger the
calculation of the factors. The chosen timeout is just a little bit longer than
the time a normal user needs in-between typing the characters. If a new
character is typed in, the running timeout is canceled and a new timeout is
started. The calculation of the factors remains identical and the look & feel
of the application doesn’t change.
Here is the JavaScript implementation of this approach:

<script type="text/javascript">
var _num = "";
var _timer = null;
function StartCalcPrimeFactors() {
var inputText = document.getElementById("inputField").value;
if (_num != inputText) {
if (_timer != null)
window.clearTimeout(_timer);
document.getElementById("outputField").value = "wait...";
_num = inputText;
_timer = window.setTimeout("CalcPrimeFactors()", 300, "javascript");
} // if
}
// calc prime factors
function CalcPrimeFactors() {
var inputText, outputText;
var prime; // try this factor (only primes will match!)
var number; // product of the remaining factors

This is not a real parallel execution of
two threads but some kind of pseudo
asynchronous programming that can
be realized by using JavaScript.
Using multiple threads inside a
Browser by using JavaScript only
cannot be done today.

_timer = null;
outputText = "";
inputText = document.getElementById("inputField").value;
if ((inputText == null) || (inputText.length == 0) || (inputText == "0"))
return;
prime = 2; // start with 2
number = parseInt(inputText);
while ((number > 1) && (prime * prime <= number)) {
if (number % prime != 0) {
// try the next factor (slowly)
prime += 1;
} else {
// found a factor !
outputText = outputText + " " + prime;
number = number / prime;
} // if
} // while
if (number > 1) {
// the last factor (a prime) is here.
outputText = outputText + " " + number;
}
document.getElementById("outputField").value = outputText;
} // CalcPrimeFactors
</script>

http://www.mathertel.de/AjaxEngine/S01_AsyncSamples/CalcFactorsAsync1.htm
For guaranteed short running functions this kind of the implementation is
acceptable for the user because the page locks itself while calculating not after
every keystroke. The delay in the case, that the calculation is executed is
hardly noticed and an input of a further character or a click with the mouse is
executed only some milliseconds later.
But with long running functions like with the calculations of the factors of a
large number a problem will arise with the time the function needs to finish.
I know 2 Methods of solving this:
1. Divide the long running function into several smaller functions
2. Real parallel execution with the assistance of a server (let's AJAX)
For sure it is possible to changed many algorithms in such a way so that
instead of a long running method several shorter steps are lined up. With the
sample of the computation of the prime factors this is also possible.
The timer is used in very short timeout intervals to check a new prime number
candidate.

<script type="text/javascript">
var _num = "";
var _timer = null;
var prime; // try this factor (only primes will match!)
var number; // product of the remaining factors
var outputText;
function StartCalcPrimeFactors() {
var inputText = document.getElementById("inputField").value;
if (_num != inputText) {
if (_timer != null)
window.clearTimeout(_timer);
document.getElementById("outputField").value = "wait...";
_num = inputText;
prime = 2; // start with 2
number = parseInt(inputText);
outputText = "";
_timer = window.setTimeout("CalcPrimeFactors()", 50, "javascript");
} // if
} // StartCalcPrimeFactors
// calc prime factors
function CalcPrimeFactors() {
_timer = null;
if (number == 1) {
// finished. all factors found
outputText = outputText + " finished.";
document.getElementById("outputField").value = outputText;
} else if (prime * prime > number) {
// the last factor (a prime) is here.
outputText = outputText + " " + number + " finished.";
document.getElementById("outputField").value = outputText;
} else {
// Debug: window.status = prime;
if (number % prime != 0) {
// try the next factor (a little bit faster)
prime += (prime == 2 ? 1 : 2);
} else {
// found a factor !
outputText = outputText + " " + prime;
document.getElementById("outputField").value = outputText;
number = number / prime;
} // if
_timer = window.setTimeout(CalcPrimeFactors, 0, "javascript");
} // if
} // CalcPrimeFactors
</script>

http://www.mathertel.de/AjaxEngine/S01_AsyncSamples/CalcFactorsAsync2.htm
However, the result is very discouraging because the running time of a
complete computation rises up with an intolerable factor so far, that the
practice fitness is no longer given.
Beside the problem that everything runs more slowly exists also the problem
that local variables cannot be used any more. All information about the
current state must be stored in global variables to be available for the next
step. That is not very useful kind of programming and again reminds me of
the "good old times" of the 80's.
Using multithreading
All the different ways of implementation up to here are not using any parallel
execution at all. That is because JavaScript is not offering any mechanism for
starting threads or for controlling a parallel execution. Here the browser
platform fails completely.
The server platforms on the other side do offer this kind of approach.
Particularly with regard to multiple users requesting for information web
servers do have a built-in mechanism for parallel execution based on unrelated
parallel incoming requests. AJAX uses this fundamental feature of web
servers as you will see.
On the client only 2 events will remain and must be processed one after the
other:
The event that starts processing:
This event is started by the user for example by clicking a button or
typing a key.
The event that ends processing.
This event is started on the client when the operation s finished on the
server and when the result of the server side execution is available in the
browser.
On the server the real work is implemented and will execute independent of
the client.
The mechanism we need between the client and the server to get the complete
work done synchronized is passing 2 messages around: one that initiates the
execution on the server and one that comes back to the client with the result of
the server’s work.

Asynchronous programming on the server
On the server asynchronous programming is also possible. During the
composition of an answer to a Web server request multiple threads can be
started in parallel to gather different information parts that will be combined
into the (only) answer for the client. Some web server platforms (ASP.NET,
Java ...) can be used for this. This kind of programming does not have to do
ANYTHING with AJAX but can be used in combination with it.

Post a Comment

You're welcome to share your ideas with us in comments.

Previous Post Next Post