Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to code with Promise from async.js?

Background

I usually write node.js script based on async.js to control the work flow. Sometimes I found that based on async.js, the code seems still a 'hell'. With multiple nest the code is not readable and tricky to maintain. I did some search here and found some useful resources - but most of them are general concepts. So I am going to ask a question. Any feedback would be appreciated.

My common code

var request = require('request');
var async = require('async');

var array = [1, 2, 3, 4 ,5 ,6];
var url = 'http://www.google.com';
async.mapLimit(array, 3, function(number, callback) {
       request(url + number, function(error, res, body){
                  //do sth
                 callback();
       });
}, function(err){//do nothing});

Question

So this time I want to replace this kind of code by Promise. Could you please help? If the question is duplicated, please suggest some useful resource url. Thanks!

like image 206
J.Lyu Avatar asked Sep 27 '16 07:09

J.Lyu


People also ask

Can we use promise with async await?

Async/Await is used to work with promises in asynchronous functions. It is basically syntactic sugar for promises. It is just a wrapper to restyle code and make promises easier to read and use. It makes asynchronous code look more like synchronous/procedural code, which is easier to understand.

Can promise function be async?

Async functions always return a promise. If the return value of an async function is not explicitly a promise, it will be implicitly wrapped in a promise. Note: Even though the return value of an async function behaves as if it's wrapped in a Promise.resolve , they are not equivalent.

Are promises asynchronous JS?

A promise is used to handle the asynchronous result of an operation. JavaScript is designed to not wait for an asynchronous block of code to completely execute before other synchronous parts of the code can run. With Promises, we can defer the execution of a code block until an async request is completed.


1 Answers

You will need to Promisify request, which can be done with native promises, but since you're using NodeJS, it would be preferable if you used the Bluebird promise library, which is almost strictly superior to the native implementation.

Then you can do:

const Promise = require('bluebird');
const requestAsync = Promise.promisify(request); // This is what bluebird saves you
// requestAsync returns a promise instead of accepting a callback.

const array = [1, 2, 3, 4, 5, 6];

const requestSingle = number => requestAsync(`${url}${number}`);

Promise.map(array, requestSingle, {concurrency: 3});

Note that Promise.map() is a Bluebird functionality, and not native.

The closest you can easily get with native is:

const arrayOfRequestPromises = array.map(requestSingle);

Promise.all(arrayOfRequestPromises)
  .then(allResults => {
    // do something
  })
  .catch(err => {
    // handle errors
  });

But then you lose the maximum 3 concurrent requests option.

like image 65
Madara's Ghost Avatar answered Sep 25 '22 17:09

Madara's Ghost