Praveen Singh

Api introduction of DEFERRED AND PROMISE IN DOJO TOOLKIT

Introduction


DOJO TOOLKIT TUTORIAL (AMD): Handling Asynchronous callbacks in Dojo using Deferred and Promise.

dojo/Deferred is a class that is used as the foundation for managing asynchronous threads in Dojo. Packages like dojo/request use this class to return a promise that gets resolved when the asynchronous thread is complete. In order trigger a callback to occur when the thread is complete, the .then() method is used. As well as the thread can be informed to cancel itself by using the .cancel() method. If the thread has completed, then the .then() callback will be executed immediately.

must pre-reads


If you are not comfortable with Promise and Defered concepts or How Asynchronous Javascript work, with help of event queue. Yo should stop here and read the below article first.


If you are not comfortable with Dojo in general, you should hit the tab which says Dojo at top and pick the article with your level.


Step by step video explanation


Re-look on Deferred and Promise lifecycle


Lets give some time and re-look and re-understand the Deferred and Promise lifecycle, which is core of everything we will cover now

code hands-on


Package Structure

Lets build the package structure as in below image

If you are facing problem in running the application with this package structure, you might want to check the "Dojo hello world" application in DOJO section of this blog.


We will concentrate on building deferred-api folder in this article.

Always run DOJO in server

As per Dojo guideline, dojo work best when it is server. So we need a static server to hold everything

If you are on mac, come to application directory and simply run python -m SimpleHTTPServer 8888 to run application on port 8888

You should see the whole package structure by hitting http://localhost:8888/

You can choose your favorite server. Things will not change much.


code

Lets kick start by creating the test html

Path:/app/dojo-deferred/deferred-api/testApi.html
 

Next we have to build the main widget class or module.

Path:/app/dojo-deferred/deferred-api/TestApiWidget.js
define([
    "dojo/_base/declare",
    "dojo/Deferred"
], function(declare, Deferred) {

    /**
     * A simple deferred based asynchronous process.
     */
    function asyncProcess() {
        var deferred = new Deferred();

        setTimeout(function() {
            deferred.resolve("I am resolved :)");
        }, 2000);

        return deferred;
    }

    return declare(null, {

        constructor: function() {
            var deferred;

            console.log("In constructor");
            deferred = asyncProcess();
            deferred.promise.then(function(data) {
                console.log(data);
            });
            console.log("Out of constructor");
        }
    });
});


            

if you run the application now, with URL similar to http://localhost:8888/app/dojo-deferred/deferred-api/testApi.html

You should see the below output in dev console of browser.

Log output:
In constructor
Out of constructor
I am resolved :)

Task chaining

Next step is to do chaining, Great thing about Promise is, it let you chain the task in sequential manner.

constructor: function() {
    var deferred;

    console.log("In constructor");
    deferred = asyncProcess();
    //chaining the task
    deferred.promise.then(function(data) {
        console.log("Then 1: ", data);
        return data;
    }).then(function(data) {
        console.log("Then 2: ", data);
        return data;
    }).then(function(data) {
        console.log("Then 3: ", data);
        return data;
    });
    console.log("Out of constructor");
}

Log output:
In constructor
Out of constructor
Then 1:  I am resolved :)
Then 2:  I am resolved :)
Then 3:  I am resolved :)

Early resolve

Lets try early resolve now.

constructor: function() {
    var deferred;

    console.log("In constructor");
    deferred = asyncProcess();


    setTimeout(function() {
            deferred.resolve("Early resolve")
        }, 1000)
        //chaining the task
    deferred.promise.then(function(data) {
        console.log("Then 1: ", data);
        return data;
    }).then(function(data) {
        console.log("Then 2: ", data);
        return data;
    }).then(function(data) {
        console.log("Then 3: ", data);
        return data;
    });
    console.log("Out of constructor");
}
Log output:
In constructor
Out of constructor
Then 1:  Early resolve
Then 1:  Early resolve
Then 1:  Early resolve

Early Reject(without short-circuit)

constructor: function() {
    var deferred;

    deferred = asyncProcess();
    setTimeout(function() {
        deferred.reject("You are rejected :(")
    }, 1000)

    //chaining the task
    deferred.promise.then(function(data) {
        console.log("Then 1: ", data);
        return data;
    }, function(err) {
        console.log("Error: ", err);
    }).then(function(data) {
        console.log("Then 2: ", data);
        return data;
    }).then(function(data) {
        console.log("Then 3: ", data);
        return data;
    });
}
Log output:
Error:  You are rejected :(
Then 2:  undefined
Then 3:  undefined

Early Reject(short-circuit)

constructor: function() {
    var deferred;

    deferred = asyncProcess();
    setTimeout(function() {
        deferred.reject("You are rejected :(")
    }, 1000)

    //chaining the task
    deferred.promise.then(function(data) {
        console.log("Then 1: ", data);
        return data;
    }).then(function(data) {
        console.log("Then 2: ", data);
        return data;
    }).then(function(data) {
        console.log("Then 3: ", data);
        return data;
    }, function(err) {
        console.log("Error: ", err);
    });
}

Log output:
Error:  You are rejected :(

Checking Progress

  constructor: function() {
      var deferred;

      console.log("In constructor");
      deferred = asyncProcess();
      var count = 0;
      setInterval(function() {
          deferred.progress((count++) +": Still working")
      }, 500)

      //chaining the task
      deferred.promise.then(function(data) {
          console.log("Then 1: ", data);
          return data;
      }, function(err) {
          console.log("Error: ", err);
      }, function(progress) {
          console.log("progress: ", progress);
      });
      console.log("Out of constructor");
  }
Log output:
In constructor
Out of constructor
progress:  0: Still working
progress:  1: Still working
progress:  2: Still working
Then 1:  I am resolved :)

Other helper methods

deferred.isResolved();      //Returns true if the Deferred is resolved
deferred.isRejected();      //Returns true if the Deferred is rejected
deferred.isFulfilled();     //Returns true if the Deferred is fulfilled
deferred.isCanceled();      //Returns true if the Deferred is cancelled

DOJO XHR with Promise concept


DOJO XHR or rquest api based out of Promise concept. You might need Promise knowledge more with XHR call in your day to day work. Below article is must read to complete the course of Promise in Dojo


Contact Me


If you want to contact me for feedback or suggestion or doubt. You can do so by commenting on Blogger article or in Youtube comments section.

You can also approach me dropping me mail directly at mails.icodingclub@gmail.com

Please prefer: comment approach

1 comment:


  1. Its very useful to me. Wonderful blog.. Thanks for sharing informative Post.

    Installment loans
    Payday loans
    Title loans

    ReplyDelete