How to actually use Q promise in node.js?

laggingreflex picture laggingreflex · Mar 27, 2014 · Viewed 26.6k times · Source

This might be a noob question, but I'm new to promises and trying to figure out how to use Q in node.js.

I see the tutorial begins with a

promiseMeSomething()
    .then(function (value) {}, function (reason) {});

but I fail to grasp where exactly does the .then came from. I guess it comes from

var outputPromise = getInputPromise()
    .then(function (input) {}, function (reason) {});

but where does getInputPromise() come from? I find no previous mention of it.


I have included it in my project like so

var Q = require('q');

// this is suppose, the async function I want to use promise for
function async(cb) {
    setTimeout(function () {
        cb();
    }, 5000);
}

async(function () {
    console.log('async called back');
});

How do I use Q and its .then here in my example?

Answer

thefourtheye picture thefourtheye · Mar 27, 2014

promiseMeSomething() is going to return a Q promise object, which will have then function in it, which is defined, like this

Promise.prototype.then = function (fulfilled, rejected, progressed) {

The simplest way to create a Promise object would be to use the Q function constructor, like this

new Q(value)

will create a new promise object. You can then attach the success and failure handlers, like this

new Q(value)
.then(function(/*Success handler*/){}, function(/*Failure handler*/){})

Moreover, if you pass a single nodejs-style function to .then function, it will call that function with the success value like this

callback(null, value)

or if there is a problem, then

callback(error)

For your particular case, setTimeout accepts the function to be called as the first parameter. So, it would take quite few lines of code to make it really work with promises. So, Q has a convenient function, for this purpose, Q.delay, which can be used like this

var Q = require('q');

function async() {
    return Q.delay(1000)
}

async()
.then(function() {
    console.log('async called back');
});

You can write it shorter like this

Q.delay(1000)
    .then(function() {
        console.log('async called back');
    });

If you wanted to call the callback function with someother value, then you can do it like this

Q.delay(1000, "Success")
    .then(function(value) {
        console.log('async called back with', value);
    });

This is going to be useful, when you want to have a delay between two functions and the second function is dependent on the first function.