M@XCode

Personal blog dedicated to computer science

How to use promises with NodeJS

Like many others i started to develop algorithm in synchronous languages. The first language I learned was TI BASIC on my calculator in high school. With that language and like many others the instructions are processed line by line. If you write a bunch of lines your sure that the line 8 will be executed after the line 7.

When developping applications with Nodejs I faced the problematic of asynchronous execution. With this fabulous tool instructions are not blocking. If you write on line 10 a task that is pretty long to execute (opening and reading a file for instance), the system will not wait till the end of this task. It will go directly to the next one on line 11. The execution is much faster but it can become a nightmare for developers that have the habbit to develop in synchronous languages. You might for instance use a variable that is not existing because it’s affectation has not be done yet !

But there is an interesting tool that is not so complicated to use : promises.

Origine of promises

Promises where implemented in Javascript as of ECMAScript 6. Originally the term was first used in 1976 in a paper proposed by Daniel Friedman and David Wise (The impact of applicative programming on multiprocessing). I want to find and read this paper, but i did’nt found it. So if somebody is looking at this article and has a PDF version i’m highly interested.

How to use a promise

The better way to understand the way promises are working is to take a simple example.
Imagine that you have to perform a database lookup, and you want to send back the result to your user when it’s done.

Let’s take as example a route in the Express framework :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// this route will be fired when an user visit the url product/1
router.get('product/:product_id', function(req, res) {
// Put the parameter in a variable for more convenience
var product_id_in_param=req.params.product_id
// Let's do the request (we use a sequelize model)
products.findOne({
where: {product_id: product_id_in_param}

}).then(function(product_data) {
// This will be executed only when the database lookup is done

res.render('product_page', {product:product_data});
});
});

How to design a function that use a promise

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function my_function_with_a_promise(){

// We will return a promise object
return new Promise(function (resolve, reject) {
// We will for instance write information in a file
fs.writeFile("info.txt", "information to write into the file", function(err) {
// If there is an error
if(err) {
// We use the reject function with the error as parameter
// To tell our program that there was an error
reject("There was an error saving your file")
}
// Else, there was no error :
// We use the resolve function to tell our program that
// The instruction was successfully executed
// You can pass a greeting message
resolve("The file was saved!");

});

}

Use our function inside our main program

Let’s imagine we want to fire this function when the user of our application visit the url /execute :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
router.get('/execute', function(req, res) {

my_function_with_a_promise().then(function(greeting_message){

// The promise executed correctly !
// Let's render the success view
// With the parameter m that will represents the greeting message
res.render('success', {m:greeting_message});

}).catch(function(error_message){

// There was an error
// Let's warn our user by renderring the error view
// along with the error message
res.render('success', {m:error_message});



});

});