-
-
Save jeffcogswell/8257755 to your computer and use it in GitHub Desktop.
// Q sample by Jeff Cogswell | |
/*=========== | |
We want to call these three functions in sequence, one after the other: | |
First we want to call one, which initiates an ajax call. Once that | |
ajax call is complete, we want to call two. Once two's ajax call is | |
complete, we want to call three. | |
BUT, we don't want to just call our three functions in sequence, as this quick | |
demo will show. Look at this sample function and think about what order | |
the console.log calls will happen: | |
===========*/ | |
function demo() { | |
$.ajax( { | |
url: '/', | |
success: function() { | |
console.log('AJAX FINISHED'); | |
} | |
}); | |
} | |
console.log('Calling demo'); | |
demo(); | |
console.log('Finished calling demo'); | |
/*==== | |
The function returns almost immediately, before the ajax call is complete. | |
That means we will likely see 'Finished calling demo' before we see the | |
results of the ajax call: | |
====*/ | |
//Calling demo | |
//Finished calling demo | |
//AJAX FINISHED | |
/*==== | |
If we want to chain a following function, when do we call it? | |
We call it from inside the success function: | |
====*/ | |
function demo() { | |
$.ajax( { | |
url: '/', | |
success: function() { | |
console.log('AJAX FINISHED'); | |
// >>>> THIS IS WHEN you would call another function <<<<< | |
} | |
}); | |
} | |
/* ============== | |
Now let's try using q. | |
=============*/ | |
function one() { | |
var deferred = Q.defer(); // Don't worry yet what this is | |
// until after you understand the flow | |
console.log("Starting one's ajax"); | |
$.ajax( { | |
url: '/', | |
success: function() { | |
// Here's where you want to call the next function in the | |
// list if there is one. To do it, call deferred.resolve() | |
console.log('Finished with one. Ready to call next.'); | |
deferred.resolve(); | |
} | |
}); | |
// The deferred object has a "promise" member, | |
// which has a "then" function | |
return deferred.promise; | |
} | |
function two() { | |
var deferred = Q.defer(); | |
console.log("Starting two's ajax"); | |
$.ajax( { | |
url: '/', | |
success: function() { | |
// Again, this is where you want to call the next function | |
// in the list if there is one. | |
console.log('Finished with two. Ready to call next.'); | |
deferred.resolve(); | |
} | |
}); | |
// The deferred object has a "promise" member, | |
// which has a "then" function | |
return deferred.promise; | |
} | |
function three() { | |
var deferred = Q.defer(); | |
console.log("Starting three's ajax"); | |
$.ajax( { | |
url: '/', | |
success: function() { | |
// Again, this is where you want to call the next function | |
// in the list if there is one. | |
console.log('Finished with three. Ready to call next if there is one.'); | |
deferred.resolve(); | |
} | |
}); | |
// The deferred object has a "promise" member, which has a "then" function | |
return deferred.promise; | |
} | |
// Test it out. Call the first. Pass the functions | |
// (without calling them, so no parentheses) into the then calls. | |
one() | |
.then(two) | |
.then(three); | |
/* ===== | |
Think about where the "then" function comes from. Each function | |
creates a new defer instance and returns that object's promise | |
member. That promise object has a "then" function. On return | |
from the first function, you get back a defer function, and | |
call the "then" function, passing the *next* function that is | |
to be called. Internally, Q stores that function. When your | |
ajax call returns, in your "success" function, you call the | |
next function by calling deferred.resolve(). | |
======*/ |
great! thanks.
thanks a lott :)
now that is a sweet example
Very instructive. Thank you.
Nice example. I just thought passing some argument to the different methods could be interesting (for ex two will work on the value from one, three from two, ...).
@Heshyo -- Excellent!
Great example -- thank you.
Check out the forks for some good updates to this example.
Finally, an example that actually makes sense to me.
thanks ... good example
Merci beaucoup pour votre exemple, ca m'a vraiment aidé.... thanks
I got it now, thanks!
Excellent description!
👍 The first Q (or promises in general) example that actually helped me understand how it works
A much better example for beginners than the one given in the project. And I totally agree that non working examples are not helpful.
Really explanatory, thanks!
This example really got me on board, thanks!
Finally a practical and well documented example. Thanks for your efforts!
awesome
super!
I ported this gist on yolpo
http://www.yolpo.com/embed.html?gist=f5efbfaeaa78aab8e23b
I liked this example - can you show one with passing return values between three function too?
is this a right way to do it? we can imagine that this works for async functions, right?
var Q = require("q");
function one(){
var deferred = Q.defer();
console.log("I am one");
deferred.resolve("hello");
return deferred.promise;
}
function two(test){
var deferred = Q.defer();
console.log("I am two " + test);
deferred.resolve();
return deferred.promise;
}
function three(){
var deferred = Q.defer();
console.log("I am three");
deferred.resolve();
return deferred.promise;
}
one()
.then(two)
.then(three)
If I want to introduce a delay between lets say two and three, I create:
function delay(ms) {
var deferred = Q.defer();
console.log("starting delay");
setTimeout(deferred.resolve, ms);
return deferred.promise;
}
And then I call:
one()
.then(two)
.then(delay(2000))
.then(three)
I don't see the delay occuring until after three runs. I see:
Starting one's ajax
starting delay
Finished with one. Ready to call next.
Starting two's ajax
Finished with two. Ready to call next.
Starting three's ajax
Finished with three. Ready to call next if there is one.
What's going wrong?
Even this example is not clear. For one thing, what is the $ variable? Is it the jQuery handle? If so, where is the require statement for jQuery? Is this only for the browser? Where is the script tag to load jQuery or Q? I tried running it in NodeJS (since that's what I want Q for). Is there a $.ajax function for the server side?
Wouldn't it be much clearer/respresentative to rewrite the example as
one()
.then(new function() {
return two();
})
.then(new function() {
return delay(2000);
})
.then(new function() {
return three();
})
.fail(new function(err) {
console.log("Something went terribly wrong between 1, 2 and 3! " + err);
});
Thanks for the great example! Here's a JSFiddle for experimenting: https://jsfiddle.net/josepi08/0nevk0a9/
New to Q and it's Promise API's,
one()
.then(two)
.then(three);
.done // Looking at the doc's https://github.com/kriskowal/q/wiki/API-Reference should you call "done" at the end?
great example