Examples illustrate the use of Promise in JavaScript

  • 2020-06-19 09:43:57
  • OfStack

Parse JavaScript SDK now provides jquery-compatible Promises patterns that support most asynchronous methods, so you'll see what that means.

"Promises" represents the next great paradigm in the javascript program, but understanding why they are so great is not easy. At its core, one promise represents one task result, which may or may not be completed. The only interface required for Promise mode 1 is to call the then method, which can be used to register callbacks when promise completes or fails, as described in CommonJS Promises/A proposal. For example, If I want to save an Prase. Object object, which is an asynchronous operation, in the old callback paradigm, your code might say:


object.save({ key: value }, {
 success:function(object) {
  // the object was saved.
 },
 error:function(object, error) {
  // saving the object failed.
 }
});
 In the new Promise In a paradigm, you can write the same code this way :
 
object.save({ key: value }).then(
 function(object) {
  // the object was saved.
 },
 function(error) {
  // saving the object failed.
 });

Not much of a difference? So what's the big deal? Well, the real power of promises is in the multiple links, when calling promise.then (func) returns a new promise, which does not execute until the previous one is complete. But there is a special case where if my callback returns a new promise via then, then promise returned via then will not be executed until the callback is completed. Please refer to Promises/A+ for details. This is a complicated rule, which can be more clearly understood through examples.


Suppose you write a piece of code to log in, find the object and update it. In the old callback paradigm, you could do this in pyramidal code:


Parse.User.logIn("user","pass", {
 success:function(user) {
  query.find({
   success:function(results) {
    results[0].save({ key: value }, {
     success:function(result) {
      // the object was saved.
     }
    });
   }
  });
 }
});

This already seems ridiculous, and what's even more ridiculous is that there's not even any error handling. But promise's chained structure makes the code look more comfortable:


Parse.User.logIn("user","pass").then(function(user) {
 returnquery.find();
}).then(function(results) {
 returnresults[0].save({ key: value });
}).then(function(result) {
 // the object was saved.
});

A: wow! A lot of!


Error handling

Error handling was not added during the code simplicity above, but when it is, you will find 1 mess in the old callback code:


Parse.User.logIn("user","pass", {
 success:function(user) {
  query.find({
   success:function(results) {
    results[0].save({ key: value }, {
     success:function(result) {
      // the object was saved.
     },
     error:function(result, error) {
      // An error occurred.
     }
    });
   },
   error:function(error) {
    // An error occurred.
   }
  });
 },
 error:function(user, error) {
  // An error occurred.
 }
});

Because promises knows if the processing is complete, it can pass in an error and do not perform any callbacks until it encounters an error. For example, the code above can be shortened to:


Parse.User.logIn("user","pass").then(function(user) {
 returnquery.find();
}).then(function(results) {
 returnresults[0].save({ key: value });
}).then(function(result) {
 // the object was saved.
},function(error) {
 // there was some error.
});

Typically, developers consider an asynchronous promise failure to be the same as throwing an exception. In fact, if a callback throws an error, promise will return a failure message. Passing an error to the next available error handler is equivalent to throwing an exception once until it is caught.


jQuery Backbone, and Parse

There are many libraries available to developers that implement promises. Like Deferred jQuery, Microsoft WinJS. Promise, ES81en. js, q, and dojo. Deferred.

However, there is an interesting point to understand. You can read here that the implementation of long and jQuery pull request discussion, jQuery does not follow the rules of Promises/A completely. Many other implementations have been used. During the experiment, I found only one place was not quite the same. If an error handler returns some additional information rather than just an promise, most implementations will consider handling the error without error passing. Instead of handling the error here, however, jquery passes it forward. Although the promise from different systems should blend seamlessly, you should be careful. One potential problem is that promises (replacing the original value) is returned in the error handler because they are treated equally.


doFailingAsync().then(function() {
 // doFailingAsync doesn't succeed.
},function(error) {
 // Try to handle the error.
 return"It's all good.";
}).then(function(result) {
 // Non-jQuery implementations will reach this with result === "It's all good.".
},function(error) {
 // jQuery will reach this with error === "It's all good.".
});


In the latest version of Backbone 0.9.10, the asynchronous method now returns 1 jqXHR, which is a type of jquery promise. One goal of Parse JavaScript SDK is to be as compatible as possible with Backbone. We cannot return one jqXHR because it does not work well on Cloud Code, so we do not all add one ES119en.Promise class, which follows the standard of jQuery Deferred. The latest version of Parse JavaScript SDK has updated all the asynchronous methods to support these new objects, and the old callback methods are still available. But based on the examples listed above, I believe you prefer a new approach. So try promises!


Related articles: