Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

Friday, August 16, 2013

Same with the promise pattern

The Promise pattern serves the same kind of goal as the one presented in the previous post, still in JavaScript.
It allows to execute some task once - and only once - some asynchronous execution is completed.
Here is an example, that can be run with node.js:
var Promise = function()
{
  var UNFULFILLED = "unfulfilled";
  var REJECTED    = "rejected";
  var RESOLVED    = "resolved";
  
  var state = {promisestate: UNFULFILLED};
  var onSuccess;
  var onFailure;
  
  this.then = function(onResolved, onRejected)
  {
    console.log(state);
    onSuccess = onResolved;
    onFailure = onRejected;
  };
  
  this.resolve = function(value)
  {
    state = {promisestate: RESOLVED};
    console.log(state);
    onSuccess(value);
  };
  
  this.reject = function(error)
  {
    state = {promisestate: REJECTED};
    console.log(state);
    onFailure(error);
  };
};

var AsyncTask = function(sometime)
{
  var i     = 0;    // Loop counter
  var max   = 5;    // Max nb loops
  var delay = 1000; // ms between loops
  var completed = false;
  var workerID, watcherID;
  
  var instance = this;
  this.performLoop = function(promise)
  {
    console.log('... Loop # ' + (i + 1));
    if (++i < max)
    {
      workerID = setTimeout(function()
      {
        instance.performLoop(promise);
      }, delay);  // There is a wait here, just to waste time.
    }
    else
    {      
      completed = true;  // Sucessful completion
      clearTimeout(watcherID);
      promise.resolve("End of loop (worker completed), clearing the watcher.");
    }
  };
  
  var timeout = sometime;
  // The promise
  this.workAndWatch = function(worker)
  {
    var promise = new Promise();
    console.log("Starting Worker");
    // The worker
    setTimeout(function() 
    {
      worker(promise);
    }, 0);
    console.log("Starting Watcher");
    // The watcher
    watcherID = setTimeout(function() 
    {
      if (!completed) // Failure to complete in time.
      {
        clearTimeout(workerID);
        promise.reject("Timeout expired, but job is not completed. Killing the lazy worker.");
      }
    }, timeout);
    console.log("Watcher & worker started.");
    return promise;
  };
};

var handleError = function(error)
{
  console.log("Error:" + error);
};

var resolution = function(data)
{
  console.log("Success:" + data);  
};

console.log("Get ready...");
var timeout = 60000;
var asyncTask = new AsyncTask(timeout);
console.log("Timeout set to " + timeout + " ms");
console.log("--------------------------");
asyncTask.workAndWatch(asyncTask.performLoop).then(resolution, handleError);
console.log("EndOfScript.");
This would produce an output like this one:

 Prompt> node promise.js
 Get ready...
 Timeout set to 60000 ms
 --------------------------
 Starting Worker
 Starting Watcher
 Watcher & worker started.
 { promisestate: 'unfulfilled' }
 EndOfScript.
 ... Loop # 1
 ... Loop # 2
 ... Loop # 3
 ... Loop # 4
 ... Loop # 5
 { promisestate: 'resolved' }
 Success:End of loop (worker completed), clearing the watcher.

Notice the 'then' method in the Promise, and the way the Promise is returned by the workAndWatch function.
Now, the real challenge would be to perform an asynchronous task as if it was synchronous. In the example above, that would display the string "EndOfScript." (6th line in the output above) at the very bottom of the output.
That is a no brainer in Java, and nicely implemented by JAX-WS.
Is that possible in JavaScript? I don't know (and I suspect not). If anyone does, please speak up.

Thursday, May 30, 2013

Who said there is no thread in JavaScript?...

JavaScript is supposed to show up as single-threaded. Is quite possible to mimic thread's behavior though, which can be pretty useful for example to deal with tasks you want to abort if they take too long to complete. In Java, this is quite natural. It is also feasible in JavaScript. Look at the code below:
  var i = 0;
  var max   = 10;   // Nb loops
  var delay = 1000; // ms between loops
  var completed = false;
  var workerID, watcherID;

  var performLoop = function(clientChannel)
  {
    console.log('... Loop # ' + i);
    if (++i < max)
    {
      workerID = setTimeout(function()
      {
        performLoop(clientChannel);
      }, delay);  // There is a wait here, just to waste time.
    }
    else
    {
      completed = true;
      clientChannel("End of loop, clearing the watcher.");
      clearTimeout(watcherID);
    }
  };
  
  var workAndWatch = function(worker, timeout, cb)
  {
    console.log("Starting Worker");
    // The worker
    setTimeout(function() 
    {
      worker(cb);
    }, 0);
    console.log("Starting Watcher");
    // The watcher
    watcherID = setTimeout(function() 
    {
      if (!completed)
      {
        cb("Killing the lazy worker.");
        clearTimeout(workerID);
      }
    }, timeout);
    console.log("Watcher & worker started.");
  };
  var callback = function(mess)
  {
    console.log(mess);
  };
  workAndWatch(performLoop, 10000, callback);
    
The work to do is describe in the function performLoop.
What we want here, is to make sure whatever runs will not take more than a given amount of time.
This amount of time is given as the second parameter of the function workAndWatch.
  workAndWatch(performLoop, 5000, callback);
I use node.js to run this script.
Let's give a 5 seconds timeout:
  Prompt> node hang.detection.js
  Starting Worker
  Starting Watcher
  Watcher & worker started.
  ... Loop # 0
  ... Loop # 1
  ... Loop # 2
  ... Loop # 3
  ... Loop # 4
  Killing the lazy worker.
And now, let's give it 10 seconds:
  workAndWatch(performLoop, 10000, callback);
  Prompt> node hang.detection.js
  Starting Worker
  Starting Watcher
  Watcher & worker started.
  ... Loop # 0
  ... Loop # 1
  ... Loop # 2
  ... Loop # 3
  ... Loop # 4 
  ... Loop # 5
  ... Loop # 6
  ... Loop # 7
  ... Loop # 8
  ... Loop # 9
  End of loop, clearing the watcher.
It actually behaves like if we were dealing with two threads. The cool thing is that we don't need to worry about any kind of synchronization... ;0)

Friday, March 08, 2013

Analog Display in HTML5

HTML5 has some amazing rendering capabilities.
I tried to mimic the rendering of those analog displays I did a while back in Java (see here), and here is what I came up with:
Of course, you need a browser that supports HTML5.
JavaScript relies on different paradigms than Java, but that works fine. Google's Chrome has some very cool features for web developers.
Here are the sources of the frame above: Right-click on the links, and use the "Save As" capability of your browser...
See here a version of Hello World, re-visited...
Enjoy!

Monday, March 04, 2013

Virtual Machines

The Java Virtual Machine (JVM) was certainly not the first virtual machine (ADA, at least, was there before...), but it is a pretty popular one.
Several - if not many - languages can now be compiled into JVM byte code, and as such, they run for free wherever a JVM exists. Among them, Scala, Groovy, Clojure,... the list is long. In short, all they need to provide is a compiler, the runtime is provided by the JVM implementation.

On another thread, there is a language that becomes more and more popular, it's JavaScript, along with JavaScript Object Notation (json), and avro, that looks a bit for json like what XML Schema looks like for XML.

The interesting parallel between the JVM and JavaScript is that JavaScript runs inside a Web browser. From this point of view, the browser could be considered like a Virtual Machine as well... The implementation of the JavaScript engine is done by the browser vendor. And as a result, JavaScript does not care about what system it's running on; just (maybe) in which browser it's running in.

More to come about that..., stay tuned!