Replacing Callbacks with Promises

In a perfect world, every function that started an async task would return a Promise. Unfortunately, most JavaScript APIs (including the native functions available in all browsers and in Node.js) are callback-based, not Promise-based. In this section, we’ll see how Promises can be used with callback-based APIs.

The most straightforward way to use Promises with a callback-based API is to create a Deferred and pass its trigger function(s) as the callback argument(s). For example, with a simple async function like setTimeout, we’d pass our Deferred’s resolve method.

 
var​ timing = ​new​ $.Deferred();
 
setTimeout(timing.resolve, 500);

In cases where an error could occur, we’d write a callback that conditionally routes to either resolve or reject. For example, here’s how we’d work with a Node-style callback:

 
var​ fileReading = ​new​ $.Deferred();
 
fs.readFile(filename, ​'utf8'​, ​function​(err) {
 
if​ (err) {
 
fileReading.reject(err);
 
} ​else​ {
 
fileReading.resolve(Array.prototype.slice.call(arguments, 1));
 
};
 
});

(Yes, you can use jQuery from Node. Just npm install jquery and use it like any other module. There’s also a self-contained implementation of jQuery-style Promises, simply called Standalone Deferred.[36])

Writing this out routinely would be a drag, so why not make a utility function to generate a Node-style callback from any given Deferred?

 
deferredCallback = ​function​(deferred) {
 
return​ ​function​(err) {
 
if​ (err) {
 
deferred.reject(err);
 
} ​else​ {
 
deferred.resolve(Array.prototype.slice.call(arguments, 1));
 
};
 
};
 
}

With that, we can write the previous example as follows:

 
var​ fileReading = ​new​ $.Deferred();
 
fs.readFile(filename, ​'utf8'​, deferredCallback(fileReading));

In Q.js, Deferreds come with a node method for this right out of the box.

 
var​ fileReading = Q.defer();
 
fs.readFile(filename, ​'utf8'​, fileReading.node());

As Promises become more popular, more and more JavaScript libraries will follow jQuery’s lead and return Promises from their async functions. Until then, it takes only a few lines of code to turn any async function you want to use into a Promise generator.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.69.53