The Promise pattern a Javascript asynchronous programming model is described in detail

  • 2020-03-30 02:53:22
  • OfStack

The Promise programming pattern is also known as thenable and can be interpreted as delayed execution. Each Promise has a unique interface called then that calls back when a Promise fails or succeeds. It represents the result of an operation that may run for a long time and may not necessarily be completed. Instead of blocking and waiting for a long operation to complete, this pattern returns an object that represents a promised result.

Many of today's JavaScript libraries, such as jQuery and Dojo and AngularJS, add this abstraction called Promise. With these libraries, developers can use the Promise pattern in real programming.

Let's first take a look at how jQuery works in general:


var $info = $("#info");
$.ajax({
    url:"/echo/json/",
    data: { json: JSON.stringify({"name": "someValue"}) },
    type:"POST",
    success: function(response)
    {
       $info.text(response.name);
    }
});

In this example, you can see when set will specify a callback after success, is a very good way to callback, this is not a Promise, jQuery official document is no longer recommended this way (http://api.jquery.com/jQuery.ajax/#jqXHR). When the Ajax call is complete, it executes the success function. Depending on the asynchronous operation used by the library, you can use a variety of callbacks (that is, whether a task succeeds or not, a callback is made in response). Using the Promise pattern simplifies this process by simply returning an object call for an asynchronous operation. This Promise allows you to call a method called then, and then let you specify the number of function(s) of the callback.

Here's how jQuery builds Promise:


var $info = $("#info");
$.ajax({
    url: "/echo/json/",
    data: {
        json: JSON.stringify({
            "name": "someValue"
        })
    },
    type: "POST"
})
.then(function (response) {
    $info.text(response.name);
});

The jQuery ajax object implements the Promise pattern by returning the XHR object, so we can call the then method. The advantage of this is that you can do it in a chain, as shown below:


var $info = $("#info");
$.ajax({
    url: "/echo/json/",
    data: {
        json: JSON.stringify({
            "name": "someValue"
        })
    },
    type: "POST"
})
.then(function (response) {
    $info.text(response.name);
})
.then(function () {
    $info.append("...More");
})
.done(function () {
    $info.append("...finally!");
});

Since many libraries are starting to adopt the Promise pattern, asynchronous operations can become much easier. But what would Promise look like from the other side? One of the most important patterns is that a function can accept two functions: a callback on success and a callback on failure.


var $info = $("#info");
$.ajax({
// Change URL to see error happen
    url: "/echo/json/",
    data: {
        json: JSON.stringify({
            "name": "someValue"
        })
    },
    type: "POST"
})
.then(function (response) {
// success
    $info.text(response.name);
},
function () {
// failure
    $info.text("bad things happen to good developers");
})
.always(function () {
    $info.append("...finally");
});

Note that in jQuery, whether we succeed or fail, we use a call to specify what we want to call.
It can also be written in this way, which is also recommended in the official jQuery documentation:


var $info = $("#info");
$.ajax({
// Change URL to see error happen
    url: "/echo/json/",
    data: {
        json: JSON.stringify({
            "name": "someValue"
        })
    },
    type: "POST"
})
.done(function (response) {
  // success
  $info.text(response.name);
}).fail(function () {
  // failure
  $info.text("bad things happen to good developers");
})
.always(function () {
    $info.append("...finally");
});

Here's how AngularJS USES the Promise pattern:


var m = angular.module("myApp", []);
m.factory("dataService", function ($q) {
    function _callMe() {
        var d = $q.defer();
        setTimeout(function () {
            d.resolve();
            //defer.reject();
        }, 100);
        return d.promise;
    }
    return {
        callMe: _callMe
    };
});
function myCtrl($scope, dataService) {
    $scope.name = "None";
    $scope.isBusy = true;
    dataService.callMe()
      .then(function () {
        // Successful
        $scope.name = "success";
      },
      function () {
        // failure
        $scope.name = "failure";
      })
      .then(function () {
        // Like a Finally Clause
        $scope.isBusy = false;
      });
}

You can try out these examples in JSFiddle and see what happens. Using Promise to work with asynchrony is a very simple way to simplify your code and really kill two birds with one stone.
More information about the Promise and the sample, can go to website (http://www.promisejs.org/) to view.


Related articles: