The newer node js has async await, which are really cool because it makes the code look better.
I was wondering if it's a good idea to make every class method async, even if it doesn't need to return a promise?
In my use case I actually sort of need that because I'm trying to share dependencies between multiple child processes, and I'm using a combination of Proxy and child process communication to achieve this. And obviously I need promises because I need to wait for the processes to respond or send messages.
But does this have any potential side effects, maybe in the long term?
To be more clear, I want to do this solely for the benefit of cool syntax.
const database = CreateProxy('database');
await database.something();
From another process.
versus some code that just requests something
from the parent process like
process.send('getSomethingFromDb');
Under the hood both use messaging, but the first one makes it look like it doesn't on the surface
If you're writing an API and your function sometimes return promises it is best to make them always return promises - more generally if a function is sometimes asynchronous (with callbacks too) it should always be asynchronous. Yes, unless of course you're also doing other things inside the function.
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.
The call to the async method starts an asynchronous task. However, because no Await operator is applied, the program continues without waiting for the task to complete. In most cases, that behavior isn't expected.
async functions use an implicit Promise to return results. Even if you don't return a promise explicitly, the async function makes sure that your code is passed through a promise. await blocks the code execution within the async function, of which it ( await statement ) is a part.
This concept is a subject for Occam's razor. There are no benefits, while there may be disadvantages.
Extra overhead (both CPU and time) is one of the problems. Promises take some time and resources to be resolved. This may take much less than a millisecond, yet a lag can accumulate.
Another problem is that asynchronicity is contagious, once it reaches module scope, async
IIFE should be used everywhere - because top-level await
isn't supported yet:
module.export = (async () => {
await require('foo');
// await was accidentally dropped
// this results in race condition and incorrect error handling
require('foo');
...
})();
And here's a good example of a disadvantage that complicates error handling:
async function foo() {
throw new Error('foo');
}
async function bar() {
try {
return foo();
} catch (err) {
console.log('caught with bar');
}
}
bar(); // UnhandledPromiseRejectionWarning: Error: foo
Despite control flow looks synchrounous-like in async
, errors are handled differently. foo
returns rejected promise, and returned values aren't handled with try..catch
in async
functions. A rejection won't be handled in bar
.
This wouldn't happen with regular function:
function foo() {
throw new Error('foo');
}
function bar() {
try {
return foo();
} catch (err) {
console.log('caught with bar');
}
}
bar(); // caught with bar
Things may become more complicated with third-party libraries that were designed to work synchronously.
I was wondering if it's a good idea to make every class method async, even if it doesn't need to return a promise?
Your code will work, but I would not recommand it for two reason :
Unnecessary memory/cpu usage
It will makes your code hard to understand. Knowing which function is asynchronous or synchronous is important to understand how a system work and what it is doing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With