Async: Documentation needs better examples

Created on 14 Jan 2019  ·  21Comments  ·  Source: caolan/async

Consider this example for map

async.map(['file1','file2','file3'], fs.stat, function(err, results) {
    // results is now an array of stats for each file
});

This basically tells me nothing except syntax. In most cases people aren't going to pass fs.stat. The examples should include use of all possible options. All examples for all functions and methods need to be updated. They are too simplistic

docs help wanted

Most helpful comment

I agree, we need much better docs. I'd also like to change many of the examples (or add mroe examples) to use async/await. However, this is something that takes time I don't have at the moment.

All 21 comments

I agree, we need much better docs. I'd also like to change many of the examples (or add mroe examples) to use async/await. However, this is something that takes time I don't have at the moment.

Maybe I can help.

How can I help with examples?

  • Examples with more async/await, less with callbacks
  • More concrete examples from real-world applications, less foo/bar
  • Things that show the "sweet spot" for Async -- things that are hard to do without the library
  • Examples the are accessible to newcomers to Node/JS that show how parameters flow through
  • More comprehensive examples showing more features of individual methods

There are @example blocks in the JSDoc comments for most methods. Go nuts!

note for that particular example, you could do

await async.map(['file1','file2','file3'], fs.promises.stat);
// or without async lib
await Promise.all(['file1','file2','file3'].map(name => fs.promises.stat(name))

or if you want an object as result

await async.auto({
  file1: async()=>fs.promises.stat('file1'),
  file2: async()=>fs.promises.stat('file2')
  file3: async()=>fs.promises.stat('file3')
})
// or without async lib
Object.fromEntries(
  await Promise.all(['file1','file2','file3'].map(async name => [name, await fs.promises.stat(name)]))
)

I'm in particular looking for a (simple) Promise-based example of async.mapLimit, even without async/await. Haven't found any non-callback example so far at all.

@flatcoding https://github.com/caub/misc/blob/master/utils/promise-concurrent.js, if you don't want await, you can replace it by a recursive function

Hi Cyril @caub,
thanks for your reply. I'm not particularly against 'await', rather for the sake of 'good examples' for the 'async' module I'd like to start with and see an implementation with basic Promise handling, including .then .catch.
I honestly struggle using async with Promises in general, so before using async/await I'd just like to start with step 1) ...
Btw., thanks for sharing your example, I'm not perfectly sure though how it relates to the async module.

I thought by "simple Promise-based example", you meant an example without any library

if you wanted an example with this library, I'm sure there are plenty

Right, so I'm fine in general with using Promises, and also I understand how to use the 'async' modules in callback style. As documentation states, without callbacks supplied it would return a Promise. So far, I couldn't fine examples, not for async.map(Limit) at least. As this thread is about 'better examples' in the documentation, I chimed in on this here...
And as said, I really couldn't get it up and running with a Promise either, even raised an issue on that.

Hi @caub, took a shot at improving the docs for collection methods, adding use cases for callbacks, Promises, and async/await.

@romanbalayan nice

the methods we use the most are async.parallel, and async.auto, do you plan to cover those too?

note: I think you could avoid the async IIFE (async ()=>{ in async/await examples, to make things lighter

@caub, updated pull request to remove IIFE. (Was using it to test locally if samples were actually working)

Yes, I would also like to cover the flow control soon. I was actually just waiting for feedback if the changes I made for the collection examples matches the expectations here.

@romanbalayan what you could do is set up that PR branch as github page (go in your fork of async, settings > Github pages > Source: (pick your PR branch)) so we can preview it in http://romanbalayan.github.io/async/v3/

@caub, great idea. Did that, and should be available now on https://romanbalayan.github.io/async/v3/

Hi @caub,

Added Promise and async/await samples for flow control methods - async.parallel, async.series, and async.auto

@romanbalayan nice! https://romanbalayan.github.io/async/v3/docs.html#auto

I feel like the callback and promises examples are always quite similar, probably worth having just one of them, since anyway when using promises, we'd rather go for async/await, and it'd lighten up stuff

Good stuff else!

@caub

Should I also remove the Promises usage example on the Collections methods as well?

I think yes you could

Also for the flow control methods, you could add examples with async inner functions, example:

const delay = (t, v) => new Promise(r => setTimeout(r, t, v));

try {
    console.time('parallel')
    const results = await async.parallel({
        one: async () => delay(200, 1),
        two: async () => delay(100, 2),
    });
    console.timeLog('parallel', results);
    // parallel: 200ms { one: 1, two: 2 }
}
catch (err) {
    console.log(err);
}

@romanbalayan great work. I wish I had found your version of the documentation some days ago! I did find out how things work by trial and error after all, but it would've been less painful with the new examples :-)
I am still not 100% sure on the utility of some of the async methods now that we have async/await and Promise.all as well as Promise.allSettled .. Basically I'm wondering if there's native equivalents of all methods at this point. (?)

const results = await async.parallel({
    one: async () => delay(200, 1),
    two: async () => delay(100, 2),
});

would be natively written:

const results = Object.fromEntries(
  await Promise.all(
    Object.entries({
      one: async () => delay(200, 1),
      two: async () => delay(100, 2),
    })
      .map(async ([k, v]) => [k, await v()])
  )
);
Was this page helpful?
0 / 5 - 0 ratings