I want to take the RSVP global object, and wrap it into a closure inside my global app closure, so that I can readily call it the way I want to call it. It also makes it easier to remember for me on how to use it, later in development.
Here's some background on that: RSVP library and a promise tutorial using it.
So given this standard usage of RSVP:
new RSVP.Promise(function(resolve, reject) {
// succeed
resolve(value);
// or reject
reject(error);
});
How can I create a wrapper for this, using the design pattern that you see below? I would like to get this RSVP object into the wrapper so that I don't have to instantiate a new RSVP Promise and define my callbacks all in the same place, every time.
I would instead like to simply call var newPromise = app.core.promise(callback)
each time I want to make a new promise.
How can I wrap this into a closure so that's possible? This is what I have so far - what's the right way?
app.core.promise = function (resolveFunc, paramObj) {
if(typeof(resolveFunc) === 'function'){
//lets move on shall we?
return new window.RSVP.Promise(function(resolveFunc, reject){
//so this is the real question, what am i to do here?
if(paramObj){
//do something with this object first, or just run it, depending on your use case
//paramObj = chopBalls(paramObj);
resolveFunc(paramObj);
} else {
resolveFunc();
}
reject(error);
});
}
};
I realize doing this barely justifies, but look at the cool way I chain them below - I think it pays off.
Then I can just do this below to make the chains, which I think is a bit cleaner for what I need, which would be great, and is my goal!
var chain1, chain2;
chain1 = app.core.promise(someSuccesCallback);
chain1.then(function(){
nowDoAChain1Operation();
}) ;
chain1.then(function(){
nowFollowupOnChain1();
}) ;
chain1.catch(function(error){
throw "we DO have an exception my friends in Chain1. This is the master catch for the chain1. Error object:" + error;
});
chain2 = app.core.promise(aChain2OperationFunction);
chain2.then(function(){
anotherChain2Function();
}) ;
chain2.catch(function(error){
throw "we DO have an exception my friends, in Chin2! This is a master catch for the chain2. Error object:" + error;
});
Does it look familiar? It's the way standard deferreds are used, this is what I am trying to mimic, because I have been using standard jQuery Deferreds like that for some time now with great success.
app.core.promise = function(){
return $.Deferred(); //ajax call promise
};
Is it possible what I'm trying to do, without defeating the purpose? (This is the design pattern I've chosen for the app. Does the design pattern make sense?).
EDIT Code Update @Benjamin,
so i would like to post my changes here, to see if this looks right. Notice how i do the last 3 returns here. Is this necessary in all cases? not right? It only depends on if you need the promise after the last return, or response is complete right? Or, does there always need to be a return?? Even in the render method which pushed forth an html response of its own? here's the e.g. code..
//app.core.js
app.core.promise = function () {
//lets move on shall we?
return window.RSVP.Promise.resolve();
};
//app.ui.js
app.ui.showAmazonResults = function(){
var promiseChain = app.core.promise(); //setup the promise
promiseChain = promiseChain.then(function(){
return app.ui.getSelectedIds(); //this runs a static function that might have a slow iteration
});
promiseChain = promiseChain.then(function(ids){
app.ui.selectedIds = ids; //just sets up a final property needed by the next call.
return app.convertData(); //this guy finishes the processing and setting up all the needed data fore the next call.
});
promiseChain = promiseChain.then(function(data){
//all properties are clean and ready to be posted, run the 3rd party call..
return app.amazon.fetchApi(); //this guy runs an api call out to a 3rd party
});
promiseChain = promiseChain.then( function(amazonData){
//app.amazon.renderData(amazonData); //important to pass in null page here, so the dashboard and old results doesn't disappear on showing more results
return app.amazon.renderData(amazonData); // this guy just renders this up front as rendered html, to the view. so i dont know it needs to be returned
});
promiseChain = promiseChain.catch(function(errorResponse){
//app.helper.log(errorResponse, 'myPage.this_ajax_call');
return app.helper.log(errorResponse, 'myPage.this_ajax_call');
});
return promiseChain; //this entire methods jobs is to completly process and do the dirty work for the cals above, and also renders, so i dont know that this eitehr needs to be returned, since its parent may not need this converted to a promise. or does it for whatever reason?
};
//somewhere inside an onready or init, where events are setup for the app all you need is after a user checks off items, then the following is ran on submit..
app.ui.showAmazonResults();
This is how i use it.