Right now I use promise.deferred in a core file. This allows me to resolve promises at a central location. I've been reading that I may be using an anti-pattern and I want to understand why it is bad.
so in my core.js file I have functions like this:
var getMyLocation = function(location) {
var promiseResolver = Promise.defer();
$.get('some/rest/api/' + location)
.then(function(reponse) {
promiseResolver.resolve(response);
)}
.catch(function(error) {
promiseResolver.reject(error);
});
return promiseResolver.promise;
}
And then in my getLocation.js file I have the following:
var core = require('core');
var location = core.getMyLocation('Petersburg')
.then(function(response) {
// do something with data
}).catch(throw error);
After reading the Bluebird docs and many blog posts about the deferred anti-pattern I wonder if this pattern is practical. I could change this to the following:
core.js
var getMyLocation = function(location) {
var jqXHR = $.get('some/rest/api/' + location);
return Promise.resolve(jqXHR)
.catch(TimeoutError, CancellationError, function(e) {
jqXHR.abort();
// Don't swallow it
throw e;
});
getLocation.js
var location = core.getMyLocation('Petersburg')
.then(function(response) {
// do something
})
.catch(function(error) {
throw new Error();
});
I guess I'm confused by what is the best way to have a central library that handles xhr requests using jquery for the calls, but Bluebird for the promises.
You can call Promise.resolve
on a jQuery thenable and have Bluebird assimilate it:
var res = Promise.resolve($.get(...)); // res is a bluebird Promise
You can also return jQuery promises directly inside a Bluebird chain and have it assimilate it.
myBluebirdApi().then(function(){
return $.get(...);
}).then(function(result){
// The jQuery thenable was assimilated
});
Your code below is close, but you don't need to catch TimeoutError
since jQuery ajax won't throw those. As for catching cancellation error. This is best practice anyway for what you're doing if you ever expect to need to cancel the request.
To convert a thenable to a Bluebird promise, you can use can call Promise.resolve
like this:
var promise = Promise.resolve($.getJSON(...));
Most JQuery AJAX functions are thenable, but for your information, if you want to convert a function that expects a callback to a promise, you can use Promise.fromNode
. The callback will be called with the arguments err, result
as is convention in the Node.js world:
var promise = Promise.fromNode(function (callback) { request(url, callback); });
If the callback doesn't expect a potential error for its first argument, you can work around that:
var promise = Promise.fromNode(function (callback) {
FB.api(url, function(response) { callback(response ? response.error : "no response", response); });
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With