简体   繁体   中英

Promises + async.js

I always read that using Promises with async.js is not a good idea. I would like to understand why.

I'm working in a project that i'm using async.eachLimit to control the limit of async operation in files, and Promises to return the result after i finish all the async operations. Example:

const maxOfAsync = process.env.maxOfAsync || 500;

return new Promise((resolve, reject) => {  
  async.eachLimit(arrayOfFiles, maxOfAsync, (file, callback) => {
    callExternalLib(file).then((data) => {
      file.data = data;
      callback();
    }).catch((error) => {
      callback(error);
    });
  }, (error) {
    if (error) return reject(error);
    resolve(arrayOfFiles);
  });
});

If i should not use both together, how to achieve the same result? Let's forget about async/await for a minute and return to the days that only Promises and async.js exists. What could i do?

Thanks.

Bluebird's Promise.map allows you to step over an Iterable and set a concurrency.

return Promise.map(arrayOfFiles, file => {  
  return callExternalLib(file).then((data) => {
    file.data = data;
    return file;
  }
}, { concurrency: maxOfAsync }) 

Promise.map will resolve a new array of values once all promises are resolved. It's not a requirement to mutate an existing array like the original code and the example above is doing.

I think that combining async callback syntax with promise syntax can confusing code. I don't think there's anything inherently wrong with it. If my code is all using promises and I introduce a library that uses callbacks, I would usually wrap that library with promises to keep my code clean.

Async.js is kind of "meh" when you want to use promises. It's good at what is does but is clearly a library that was built to ease the use of callbacks and that was later upgraded to try to work with promises. It even tries to make some auto-magic decompilation of the code to try to know if a function should be handled like an async function returning a promise or a non-async function using a callback (and, like all libraries making decompilation, it can and will fail if you compile your code with Babel or similar tools).

I recently published a library which is an alternative to async.js and that was precisely made to use only Promises (and async/await), thus making a fully-consistant library to work using those newer tools.

The result is named modern-async and is here: https://nicolas-van.github.io/modern-async/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM