This is not an antipattern. Async await was not created for parallel processing but for reducing hanging worker thread when waiting for io completion. Use parallel libs for this.
I think if it's not an antipattern then it's at least something that developers should avoid, waiting for multiple unrelated Promises, only starting each one after a previous one is finished is clearly not good.
If you were doing database calls in those async methods, then your "improved" solution would break, because most database drivers aren't thread safe (I'm not aware of any). So you should really understand what you're doing, when trying to improve something.
Right, except that I write that no DB driver (I am aware of) is thread safe. If you have a separate connection object, your connection doesn't need to be thread safe anymore. Thread safety is always defined on a single object or static methods. Also if you have separate connections, you can share the same transaction unless you'd start using distributed transactions, which probably isn't what you want.
I was talking about C# (that's the first tag on the post), but nodejs should behave the same - although it seems, that there is at least one db driver for nodejs, which is thread safe - github.com/brianc/node-postgres/is... - which I find very interesting, although it might completely screw up the result that you get, if you are running any DML statements. Anyhow, having separate await statements for each async statement isn't an anti pattern, as others have pointed out, it simply solves a different problem - reducing the number of idle threads, and threads are expensive, or in JS - you simply only have a single thread and awaiting an async operation frees up that thread to do other tasks, it's not wasted.
Can print separate values for i, because it can be changed by another piece of code which jumps in while we're waiting.
If my understanding as described above is correct, than it's straight forward to design a system, which starts breaking when you remove the immediate await. It might not be as easy as in c# where even i++ isn't stable unless you lock it (or do some other stuff), but it's definitely possible. Maybe that's what you meant, that it's not an issue? Otherwise I'm intrigued to know, what node js has up it's sleeve.
There's a fair bit to unpack so apologies if I miss something.
Regarding database access using async/await in node: using Promise.all does not result in multiple threads (you can see this by sticking breakpoints in the methods; only one will run at a time). All you're doing with await is waiting for the asynchronous action that returns data to return its value before continuing. These two functions are functionally identical:
Worth underlining that I explicitly said unrelated promises. If promises have interdependencies then yeah, they need to wait for each other.
Regarding your examples, the only way i could be changed during an await is if another callback has i in its scope and changes it. In which case, if you want i to change, you should be awaiting the promise that you expect to make that change. If you don't want i to change, don't await anything, the code is synchronous and you can safely run the rest of your code knowing that, even though you triggered some async functions, they won't resolve until the next event loop at the earliest.
If that misses your point I apologise. Do you have a more fleshed out example that we can see to try and clarify things?
Since those are most likely all io bound calls (say rest or DB calls) there's no processing going on and using async/await is exactly the right solution here. Parallel libraries are only useful if you want to parallelize actual CPU bound work.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
This is not an antipattern. Async await was not created for parallel processing but for reducing hanging worker thread when waiting for io completion. Use parallel libs for this.
I think if it's not an antipattern then it's at least something that developers should avoid, waiting for multiple unrelated Promises, only starting each one after a previous one is finished is clearly not good.
If you were doing database calls in those async methods, then your "improved" solution would break, because most database drivers aren't thread safe (I'm not aware of any). So you should really understand what you're doing, when trying to improve something.
Actually no, almost all dbs are threadsafe, as long as each thread opens a separate connection.
Right, except that I write that no DB driver (I am aware of) is thread safe. If you have a separate connection object, your connection doesn't need to be thread safe anymore. Thread safety is always defined on a single object or static methods. Also if you have separate connections, you can share the same transaction unless you'd start using distributed transactions, which probably isn't what you want.
Are you referencing C# here? Because your comments do not apply to JavaScript.
I was talking about C# (that's the first tag on the post), but nodejs should behave the same - although it seems, that there is at least one db driver for nodejs, which is thread safe - github.com/brianc/node-postgres/is... - which I find very interesting, although it might completely screw up the result that you get, if you are running any DML statements. Anyhow, having separate
await
statements for each async statement isn't an anti pattern, as others have pointed out, it simply solves a different problem - reducing the number of idle threads, and threads are expensive, or in JS - you simply only have a single thread and awaiting an async operation frees up that thread to do other tasks, it's not wasted.Thread safety is not really a concern here. I think you might be misunderstanding how Node.js works.
Ok, enlighten me. This is my understanding of JavaScript engines, and it might be completely wrong or just off for node js:
JavaScript is single threaded, with an event loop to support async operations. That means,
i++
is always stable,That code above also prints the same value twice, always. But...
Can print separate values for i, because it can be changed by another piece of code which jumps in while we're waiting.
If my understanding as described above is correct, than it's straight forward to design a system, which starts breaking when you remove the immediate await. It might not be as easy as in c# where even
i++
isn't stable unless you lock it (or do some other stuff), but it's definitely possible. Maybe that's what you meant, that it's not an issue? Otherwise I'm intrigued to know, what node js has up it's sleeve.Cheers
There's a fair bit to unpack so apologies if I miss something.
Regarding database access using async/await in node: using Promise.all does not result in multiple threads (you can see this by sticking breakpoints in the methods; only one will run at a time). All you're doing with await is waiting for the asynchronous action that returns data to return its value before continuing. These two functions are functionally identical:
Worth underlining that I explicitly said unrelated promises. If promises have interdependencies then yeah, they need to wait for each other.
Regarding your examples, the only way
i
could be changed during anawait
is if another callback hasi
in its scope and changes it. In which case, if you wanti
to change, you should beawait
ing the promise that you expect to make that change. If you don't wanti
to change, don'tawait
anything, the code is synchronous and you can safely run the rest of your code knowing that, even though you triggered some async functions, they won't resolve until the next event loop at the earliest.If that misses your point I apologise. Do you have a more fleshed out example that we can see to try and clarify things?
Since those are most likely all io bound calls (say rest or DB calls) there's no processing going on and using async/await is exactly the right solution here. Parallel libraries are only useful if you want to parallelize actual CPU bound work.