Using Bluebird to manage your Promises

Using Bluebird to manage your Promises

There are many Promise implementations out there, my favorite one is called Bluebird because it is fast, consistent, lightweight and packed with very powerful features. Bluebird can be used in both client-side and server-side, which makes it super easy to implement universal applications.

My favorite feature of Bluebird is that you can “promisify” anything directly, also works on prototypes too. Below is a simple piece of code to read some data line by line and and omits empty lines.

JavaScript
1
2
3
4
5
6
const Promise = require('bluebird');
const readFile = Promise.promisify(require('fs').readFile);

readFile('./data.txt', 'utf8')
.then(data => data.split('\n').filter(x => x.length > 0))
.catch(console.error);

Now let’s do something more interesting, say that each line contains a URL and we want to download the file in sequence i.e. wait for current to finish before continuing and store it somewhere.

JavaScript
1
2
3
4
5
6
7
8
9
10
11
readFile('./data.txt', 'utf8')
.then(data => data.split('\n').filter(x => x.length > 0))
.each(link => {
return new Promise((resolve, reject) => {
http.get(link, res => res.pipe(
fs.createWriteStream(path.basename(link)))
.once('close', resolve)
).once('error', reject);
});
})
.catch(console.error);

As you can see it is very easy to implement such a thing with just a simple “each” call. If you want the files to be downloaded all as once, simply use “all” instead.

Next scenario, when building your API and you want to cache some data but want to make it consistent when making calls with promises but the cache data need’s to be returned immediately while retaining a Promise API. To solve this you simply store the promise and call .then() multiple times as needed.

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let cached = null;
function getData() {
return cached || (cached = readFile('./data.txt', 'utf8'));
}

// lazy load the data
app.get('/endpoint', (req, res) => {
getData().then(res.send.bind(res));
});

// clear the cache
app.delete('/endpoint', (req, res) => {
cached = null;
res.sendStatus(200);
});

As you can see Bluebird is very consistent and really easy to use. I’ve only just scratched the surface, however if you would like to learn more I would recommend you take a look at their documentations. You will find a lot of useful functions each that are useful for every async situation you will encounter.

Overall I find Bluebird saves me alot of time when writing very complex API, it helps me manage it better and makes it super efficient. I really hope you find this article useful, give Bluebird a go and let me know what you like or dislike about it in the comments below.