question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Treat functions without a callback as promises

See original GitHub issue

The current behavior is very surprising:

await async.parallel({foo: async()=>Promise.all([1,2])})
// { foo: [ 1, 2 ] }
await async.parallel({foo: ()=>Promise.all([1,2])})
// waits forever because non-async function expects a ballback

Because for short functions, it’s tempting to just write foo: () => doSomething(). It’s very easy to forget the async keyword there

But currently this won’t work, it needs to be written as foo: async () => doSomething()

Could we rather check if a callback is passed or not, instead of checking if the function is an AsyncFunction?

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:1
  • Comments:12

github_iconTop GitHub Comments

3reactions
m0uneercommented, Aug 10, 2020

@caub This is the reason https://github.com/caolan/async/blob/8aecf108b3922bc5211036706a0f6f75e02bd42b/lib/internal/wrapAsync.js#L3:L5

function isAsync(fn) {
    return fn[Symbol.toStringTag] === 'AsyncFunction';
}

This way, it’s easier to check if the function returns a promise without actually calling it. But still agree with you that this is against the async/await conventions. As adding an async keyword without an internal await is considered a bad practice in most of cases actually.

from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

The body of an async function can be thought of as being split by zero or more await expressions. Top-level code, up to and including the first await expression (if there is one), is run synchronously.

… and so it’ll be useless and worst it will add some performance overhead if the code is transpiled by babel for example as it’ll add more code and steps just because of the existence of the async keyword

For example, the following:

async function foo() {
   return 1
}

…is equivalent to:

function foo() {
   return Promise.resolve(1)
}

but with this library,

async.mapLimit([1], 1, async v => v)

and

async.mapLimit([1], 1, v => Promise.resolve(v)))

are not equivalent!

3reactions
flatcodingcommented, Aug 27, 2019

Even with this issue closed, as of the linked issue above, I’d like to re-emphasize on @caub statements here. The current behaviour confused me a lot, and while I (kind of) understand the technical limitations discussed here, I believe that the documentation is simply not in line with the current behaviour. For e.g. mapLimit it says “Returns: a promise, if no callback is passed” - I started with the callback version, and then basically left out the callback and was surprised that I don’t get the Promise (because I didn’t have the ‘async’ keyword). also, the ‘callback’ statement in the iteratee function isn’t needed then, instead you need to ‘return’ a value. So, either the behaviour should be changed (preferred) or at least documentation and examples should be aligned in my point of view to avoid confusion.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Using promises - JavaScript - MDN Web Docs
Essentially, a promise is a returned object to which you attach callbacks, instead of passing callbacks into a function. Imagine a function ......
Read more >
Aren't promises just callbacks? - Stack Overflow
Promises are not callbacks. A promise represents the future result of an asynchronous operation. Of course, writing them the way you do, you...
Read more >
Promises in Node.js: An alternative to callbacks - IBM Developer
A function has one return value. When passing Promise.all two promises that complete, onFulfilled triggers with one argument (an array with both ...
Read more >
Introduction to ES6 Promises - 4 functions to avoid callback hell
Callbacks are just blocks of code which can be run in response to events such as as timers going off or messages being...
Read more >
Callback and Promises in JavaScript - Medium
Here a function is passed as a parameter inside another function. In asynchronous programming, a piece of code does not sit idle. It...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found