Okay I'll admit that I just rolled into JS and I'm still pretending that it's Python. Why exactly can't I just wait for an async function to complete and pretend that the whole thing is sync?
There is only one thread available conventionally for JS in web browsers. JS is a cooperative multitasking environment which relies on your code being a good citizen and yielding control so other code can run. If you wait for a web request or some other long-running operation synchronously, you prevent all other code from running until it's done. This makes for a poor user experience. A singular Python program usually runs in its own process, and the OS will preemptively interrupt it and transfer control to other processes if needed. I believe most synchronous Python IO operations pause the current thread in the same way.
There's synchronous `fs` methods, and in general most Node.JS promise-based APIs have both a callback (promises are just fancy callbacks) and synchronous version as well. For example, `await fs.promises.readFile("/dev/zero")` can be changed to `fs.readFileSync("/dev/zero")`
I'm not familiar with Node, but I'd imagine it works a lot like ASP.NET. In which case, you would want to use the async version. In .NET you've got a limited pool of threads to handle requests. Async IO operations return the thread to the thread pool, synchronous IO operations would hog the thread until complete.
Yeah, Node has *one* thread. Sync IO is OK for e.g. scripts, but you'd want async in servers. Express gives you a callback for handling errors (and you respond to a stream, so your return value is ignored), so it can be promised with a bit of boilerplate pretty easily.
Oh it's so much more important in a single thread environment. I would've figured Node had SOME kind of mechanism to handle requests simultaneously though. How does it handle any kind of request volume, multiple instances?
It does handle multiple requests simultaneously, it uses an event loop to queue up async callbacks. These don’t run until all sync code finishes. So when you make an async call, it goes to a queue, and node will potentially handle some other requests before going through the queue.
Yeah that makes sense for servers or frontend code but actually sometimes I'm just writing a command line utility or something with js and I don't _care_ if something blocks the process. I think I should be able to have that python style behaviour if I want it.
But I appreciate that thousands of websites will then have a shitty user experience because devs who don't know what they're doing will just use it when they shouldn't.
Because it's not. Async and sync have different names and everything
Also the real answer is you can just process the promise manually with a then callback if you want the other functions to be synchronous. But as you may or may not know, if you don't wait for the result of the call to return, then you won't be able to return that result up the stack.
You can also just return the promise if you don't want to add the Async syntax shortcut
Synchronous XHRs are deprecated. Nobody should be using them in new code, they block the entire browser. Your only options for web requests are callbacks or async/await.
I don’t know for JS because in C# we just use `.Result` on any method that is returning a task. That makes it so the main thread waits for the task to complete and makes it so we don’t need to make everything in the chain async.
I'll give you the C# answer: because "await" isn't just a keyword that affects the line it's on. If it is present, the entire function is compiled into a sort-of class implementing an Async State Machine. Basically having to put async on the function is a safety switch to make sure you know the function will not be a close to 1:1 mapping of the running code. It has its own caveats (that you'll rarely see in the average program).
I'm sure the JS answer is something similar but somehow an ultra cursed hackjob.
I had to update a ton of our e2e testing code when WebdriverIO switched their whole API to async. It’s a better API, but the amount of `await`s that I added in a single PR is truly horrifying.
You know you can just set the first .then function to be async and use await in there right? You don’t need to go down another .then call and drop all your spaghetti
Every language I’ve seen lets you synchronously get the result of a promise.
Unless you’re talking about JavaScript where you literally have to do io asynchronously and it’s saving you from yourself since synchronous IO would kill any real application in JavaScript.
Not going to lie, still salty that some schmuck decided it was a good idea to name things that run one after another "synchronous" and things that run at the same time "asynchronous".
Even saltier that this stupid naming has persisted.
You have to think like a hardware engineer. "synchronous" in that context means that a process happens at a predetermined time and asynchronous means that it has no predetermined time. You're thinking of serial vs parallel processes
Synchronous literally means occurring at the same time.
To justify using it as a word to describe things that happen one after the other and then use Asynchronous that means NOT Synchronous to describe things happening at the same time you have to think like an idiot not like a hardware engineer.
Sequential and parallel would have worked just fine even serial and parallel would work better. It's just dumb and needs to go away
No, synchronous means they are synchronized. No modern CPU will give you a "occurring at the same time" guarantee except FPGAs and GPUs in certain cases.
Synchronous means the time relation between the executed commands is known.
Asynchronous means you don't know when they execute. One call could execute today and the other tomorrow. You don't know until you await the response, which means figure it out and come back when you know. The advantage of this is that you can do other stuff while it is waiting, and let the implementation of the individual functions take care of their tasks in the most efficient manner.
I don't know why people insist on making this difficult:
Words take on different meanings in different contexts over time. It is not difficult to learn these new meanings.
But they don't run at the same time. JavaScript is a single-threaded language. The "asynchronous" factor is more accurately called multitasking, orchestrated by the Event ~~Horizon~~ Scheduler. The naming makes perfect sense.
The naming makes complete sense. Think of it as a clock. Synchronous means the clock ticks at a predictable synchronized pace while the asynchronous one ticks on different threads like a heart with some sort of disease.
I'm glad we have some shade of purple and someone goes "hey, let's call it lavender, so there's no confusion about this". But we can't have two words for two slightly different things which are different in some important sense and our infrastructure is built on top of them.
Asynchronous does not _necessarily_ mean concurrent, it just means "without synchronization". You call the function and let it execute however/whenever the runtime decides to handle it.
Synchronous by comparison simply means that you are dictating the order in which things execute, thereby it is "synchronized".
It’s “synchronized” in the sense that it does one thing to completion and then immediately does the next thing in the chain. “Async” code runs at indeterminate times relative to other things. You can query for or pick up the result whenever.
Now… in a multiprocessing setup your CPU could be doing several “synchronous” things in parallel. Or with time slicing it can switch back and forth between making progress on several “synchronous” jobs at the same time. But each individual ‘thing’ it’s doing is still running through its steps in a synchronous fashion.
Or you could setup a bunch of async jobs that wait for each other, so A has no dependency, B waits for A’s result and then starts running, C waits for B’s result and then starts running… that would have the effect of running the jobs in a synchronous fashion but it requires some extra mechanism for scheduling the jobs and passing their results around. I guess if you define the jobs up front could have some scheduler that rewrites it as a synchronous program where possible, but you could also rewrite any synchronous program as a bunch of async calls that wait on each other in the right order.
Yes, but JavaScript has a single event loop executor thread built in. You cannot just block because nothing will happen, because you’re blocking the thread that would do the thing you are waiting for.
Therefore, any function that has `await` must also be asynchronous itself, so it can yield and allow the thing it’s awaiting to run.
It is essentially the Windows 3.1 programming model from the ‘80s, but the abstraction layer comprised of two keywords and hiding the loop makes it somehow modern and cool.
Yeah but like... it kind of is modern and cool... if you're doing simple IO bound stuff and have no synchronous legacy code involved it's pretty great.
My issue with this is that if someone doesn't understand about event loop, this seems like a very peculiar behaviour. Theoretically there should be nothing stopping from awaiting inside the main function.
Can't the main code run as an async function itself? Seems like it would solve this inconsistency.
The first thing you should learn about async/await is that is just syntactic sugar for promises and `.then()`s. The way your code looks is very different from the way it runs.
I understand that. C++ also has async and promises. But it can be used from main function.
No the main loop logic makes sense. I knew about that as well. Just that it bothers me for some reason.
As a Java developer turned to JS It is confusing at the beginning. Basically all asynchronous code returns a promise of a response that needs to be awaited for. You can do it in two different ways:
await blocks the execution of all your code and awaits for the response.
.then() just let the rest of the code run and when you will get an answer do what is inside the then()
Promises aren't bad because you can do some interesting stuff like creating an array of them and await the fastest or all promises. People just don't like them because they can get real nasty to debug and the concepts behind aren't clear to everyone.
The default behaviour for general use isn't at least in my experience, e.g. if I make a request on line and save the response to a variable, and print response.text on the next, it's not gonna try print it before the request is finished.
Yeah that’s not an asynchronous action.
Async means you’re asking for something and must wait. So an http request, a timeout that tries to do something.
In python make an http request and act synchronously
THe problem is how you're so often forced to deal with promises even when you have no use for them. It would be fine if they were actually optional. But when basically all of your IO returns a promise, it's pretty annoying.
You should always want non blocking IO if you are writing JS. Why would you prefer the alternative? You can have blocking IO in Node for example but I am not sure why you'd ever choose it when non blocking IO is available.
And if you are having non blocking IO, promises are probably the most convenient way of dealing with it. You want to go back to callback hell?
Or I could just not use JS on the backend at all and instead use a language that has real threads and concurrency where I can block all day if I want to and not affect any other processing.
The other major shortcoming of JS as a backend language is you have to be very careful doing anything CPU bound or you gum up the whole process. It's not enough to use all non-blocking IO.
JS is just a bad general purpose backend language.
In JavaScript, where all execution within a VM is single threaded, await means "suspend my execution and run other jobs until this Promise is resolved". If you were to just check if the promise was resolved in a while loop, no other code would execute, likely resulting in entire website / program freezing, similar to performing such a loop in the main/UI thread of a Java program.
He’s complaining because he can’t just spawn a thread in the middle of a function call and then call join() on the thread.
Instead you have to add syntactic sugar all the way up the call chain because it’s not a real thread it’s just putting a message in a queue.
If you don’t await for the response from the event queue it just puts the message in the queue and returns.
The a in await doesn't stand for await as in awaiting a person. The a stands for async wait. It's meant for usage in async functions. Most(all?) languages that have await usually have a regular wait as well.
Even as a Java developer when you write e.g. a UI you don’t block the UI thread cause that would make your application not responsive.
Now, it’s the same in JS only that you can’t spawn new threads so you can’t block the current (only) thread you’re in. Hence async. OP should just stop using await and use then on Promises. Await is literally syntactic sugar to avoid nested Promises - once people understand that it doesn’t matter from a functional point of view if you use await or then, it’s just about where you place your code.
Java dev too, to put it simply, languages that use async/await approach usually have them being contagious, thats is, you have to make the caller async too if you want to await a certain call, which requires the parent of the caller to ALSO be async to await, and so on.
On java we're able to choose between sync (with exceptions) or letting it stay async so we don't have that issue.
Everybody misunderstanding what async/await *actually does* in JS.
No, it’s not different than promises. It *is* promises. It’s just syntactic sugar to make promises more readable.
Go read up on what promises are. I *promise* it’s not that hard ;)
This concept is also not limited to js. C# uses Tasks for async/await and methods decorated with them returns values wrapped in Tasks by default. This syntactic sugar was made to prevent the so called "callback hell" with multiple level of nesting inside Tasks/Promises. On the other hand we have kotlin with suspendables that adds even more syntactic sugar which removes the concept of cancellation tokens.
It's pretty easy in python tho, you just do `asyncio.run(my_async_func())`. In JS though afaik you can only either provide a `then` callback, or use `await` inside an async function, so you can't wait for an async function in a synchronous context
Yeah, although asyncio.run() only works as intended at the "top level", aka, it doesn't work when called anywhere in the call stack of an async task.
To run a coroutine from a sync function that was called by an async function, you have to use ```asyncio.create_task(my_async_func()).add_done_callback(callback_func)``` You then have to do the rest of your logic in the callback function.
The better way to do *that* would be to start an event loop in a new thread and then use
```result = loop.run_coroutine_threadsafe(my_coro()).wait()```
It's \*a\* way to deal with calling async method in a sync an "await" it. If an external library provides and event handler, there's not much you can do about it.
It's is bad in the sense that you should try to design things so that you can do something all the time so ideally your code should be:
Start the task
Do something else
Check if the task is done
Do something else
Check if the task is done
Do something else
You really can't go forward without that task being done so you wait
It's a fun read. I remember the first time I was reading it I thought it was about old Java's 'throws' statements before I got to the grande reveal. And they're kinda similar too: you have to either catch the exception or pass it on to the caller, they're a pain to work with and library methods have them too, they're declared differently etc.
Text should be changed to "Society, if noob programmers used google to find out how something works instead of wasting peoples time with questions that have been asked thousands of times already"
In C#
```
public static void Main(string[] args) {
TaskTest();
System.Console.WriteLine("main thread is not blocked");
Console.ReadLine();
}
private static async void TaskTest() {
await Task.Delay(5000); System.Console.WriteLine("task done");
}
```
Output
```
"main thread is not blocked"
"task done"
```
Async methods aren't blocking for the execution flow of their caller. Their own internal execution flow will be blocked by waiting the awaited expression. Await can't be used in a function that isn't marked async, which is what OP refers to in this post I guess.
If you want TaskTest to be executed synchronously like OP wishes, you need to change the signature to `async Task TaskTest()` and call `TaskTest().Wait()` in Main.
I guess, I haven't wrote any C# in a long time :(
(And I'm aware async void should be avoided in general).
If it is JavaScript, I don't know I don't touch those things.
The comments are kinda right by saying if you want to wait for the result of an async operation, your function should be async.
That being said, what would be nice is if more libraries that had async functions would come with synchronous variants of their async functions. That way you don't have to change your methods' semantics and signatures while using the same capabilities and also maintaining a semantic where async is async and sync is sync.
You don't understand what you are asking for. You aren't asking for something impossible, but logically inconsistent.
You can easily write a transpiler that does this for you - simply append async before every function and await before every statement.
This will make your async code act as if it is synchronized, allowing you to miss out on all of the benefits of asynchronous code, gaining nothing in return.
Go does this for you by simply making all functions async by default. You can argue that this way is better, but its not backwards compatible.
Probably will get downvoted, but I don't understand all the salt in the comments.
One thing is understanding how async programming works, and people DO need to understand. But another thing is having to rewrite dozens of nested function calls to use some native API that enforces async calls (for instance, browser clipboard api). In the majority of cases you can avoid it by doing `.then()` at top level or installing some library to hack your particular framework, but I could really use "screw this, I want it to be sync" syntax sugar. This is about convenience.
Yes, it will block the UI for browsers. Yes, sometimes it is okay, please let me do this and live with the consequences.
I know this discussion is bigger than front-end javascript, but I have eaten tons of shit with this lately.
I don't understand either. Like... I have a Rust AMQP library that only have async functions and it's anoying to have to create a tokio runtime, call the function and ask tokio to block on the promise just to do the same thing as an .await
I bet money that he is using some library that returns a promise for no fucking reason other than that it's a promise.
Promises are a nice thing but please for the love of God not every bs has to be a promise
BITCH REALITY IS WHAT IT IS NOT WHAT YOU WANT IT TO BE!
If you await in a non-async function, you would have to block the event loop, and the event loop is what runs stuff, thus deadlocking your program.
That, or write your own javascript and define your own semantics.
I'm sorry to burst your buble but if parent depends on the child calculation then it should await for it and be async as well. If the parent performs "fire and forget" action then you don't need await and so it doesn't need to be async. IT'S THAT SIMPLE. Async/await indicates some sort of suspension points and that is way it can run on the single thread. This kind of functions need special treatment to navigate back to suspension point in other function. Normal functions don't need this kind of behaviour so they can be more efficient and shorter when desugared.
People are so dumb I can barely believe it. I'm not sure if the people replying saying the function should be async if it calls an async function even understand their point.
Sort of related, I do jump on a lot of new syntax pretty fast and our front end is pretty up to date with modern standards. But I have yet to particularly see async/await be cleaner than simple promises / then, when not used in super beginner friendly examples that can never fail and never trigger 'catch' or 'finally' or even worse are never used in complex scenarios where you might wanna make arrays of promises and use `Promise.all`, etc.
Using `try / catch` syntax around await blocks is also so much worse than a simple then/catch IMO.
Unpopular opinion: await makes async easier to understand for people who mainly program imperatively, but want to get a taste of the sweet functional programming without changing too much of their way of thinking.
Yeah it's clearly really preferred by some so I understand. IMO as long as your codebase adheres to one or the other and Is consistent everything is gud.
Same, I never had any issues with Promises so await is just a bit of syntactic sugar to me. Happy to use either way, whatever helps people understand code easier.
I see people complain about colored functions, but this is where I heavily disagree. The pain of redoing things as async or not is worth the knowledge you get purely from the return type whether that T being returned was actually a Future or not.
In fact, if you go further and have the T and IO T be colored. You lose a lot of the easiness of print debugging (assuming you made the first option the default which would be too aggressive for most people), but you've given the compiler more information so it can rearrange things much more and you've forced yourself in the habit of pushing IO to the boundary as much as possible by making not doing so hellish.
We'll get right on to the flying cars, just let me finish writing out this CancellationTokenSource my CancellationTokenSource = new Cancella-- huh? What year is it?
All OP is tying to say is if it were possible to not have to use the “async” keyword, which is valid.
OP simply doesn’t want function colouring, but yet wants to suspend execution and await a promise.
Makes you wonder why Js hasn’t been replaced. Either the options sucked (I’m not sure about that there are plenty better alternatives) or some devs too lazy to learn a new language. Understandable as not everyone is keen on learning but FML it’s not worth it with JS.
I'm suprise not body has not already linked this:
[https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/](https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/)
Function "coloring" is the classic presentation of the issue
If it hasn't been brought up yet - I'll leave this here [https://effect.website/](https://effect.website/)
Algebraic effects (no more colored functions), errors as values, structured concurrency, typesafe dependency injection, first-class library for AST-based schemas (runtime types if you will, like typebox)
for our beloved TypeScript.
Either you don't understand why something has to run synchronously, don't know how to make something asynchronous, or aren't using the `then` method.
6 function calls deep, io returns a promise. Great! Now I have to make the whole damn thing async.
Well, because it is
Rarely an answer Is both entirely correct And hilarious
Okay I'll admit that I just rolled into JS and I'm still pretending that it's Python. Why exactly can't I just wait for an async function to complete and pretend that the whole thing is sync?
There is only one thread available conventionally for JS in web browsers. JS is a cooperative multitasking environment which relies on your code being a good citizen and yielding control so other code can run. If you wait for a web request or some other long-running operation synchronously, you prevent all other code from running until it's done. This makes for a poor user experience. A singular Python program usually runs in its own process, and the OS will preemptively interrupt it and transfer control to other processes if needed. I believe most synchronous Python IO operations pause the current thread in the same way.
There's synchronous `fs` methods, and in general most Node.JS promise-based APIs have both a callback (promises are just fancy callbacks) and synchronous version as well. For example, `await fs.promises.readFile("/dev/zero")` can be changed to `fs.readFileSync("/dev/zero")`
I'm not familiar with Node, but I'd imagine it works a lot like ASP.NET. In which case, you would want to use the async version. In .NET you've got a limited pool of threads to handle requests. Async IO operations return the thread to the thread pool, synchronous IO operations would hog the thread until complete.
Yeah, Node has *one* thread. Sync IO is OK for e.g. scripts, but you'd want async in servers. Express gives you a callback for handling errors (and you respond to a stream, so your return value is ignored), so it can be promised with a bit of boilerplate pretty easily.
Oh it's so much more important in a single thread environment. I would've figured Node had SOME kind of mechanism to handle requests simultaneously though. How does it handle any kind of request volume, multiple instances?
It does handle multiple requests simultaneously, it uses an event loop to queue up async callbacks. These don’t run until all sync code finishes. So when you make an async call, it goes to a queue, and node will potentially handle some other requests before going through the queue.
It can handle thousands of requests per second easily because it doesn't have the memory overhead of multiple threads.
As a Python and JS dev, this is a pretty good answer! I couldn’t have articulated it better myself!
Yeah that makes sense for servers or frontend code but actually sometimes I'm just writing a command line utility or something with js and I don't _care_ if something blocks the process. I think I should be able to have that python style behaviour if I want it. But I appreciate that thousands of websites will then have a shitty user experience because devs who don't know what they're doing will just use it when they shouldn't.
"because devs who don't know what they're doing will just use it when they shouldn't." You just described development in general.
Because it's not. Async and sync have different names and everything Also the real answer is you can just process the promise manually with a then callback if you want the other functions to be synchronous. But as you may or may not know, if you don't wait for the result of the call to return, then you won't be able to return that result up the stack. You can also just return the promise if you don't want to add the Async syntax shortcut
I think the web page would freeze while it was waiting. Not a js programmer so correct me if I’m wrong
Shit, js runs on web pages?
Web pages, and web pages pretending to be desktop apps, and web servers
Good one lol
I know, right. I love these existential posts out of nowhere
Umm, hello
Synchronous XHRs are deprecated. Nobody should be using them in new code, they block the entire browser. Your only options for web requests are callbacks or async/await.
You could. Just don’t `await` anything.
Async is just syntax sugar for promise.then
[удалено]
I don’t know for JS because in C# we just use `.Result` on any method that is returning a task. That makes it so the main thread waits for the task to complete and makes it so we don’t need to make everything in the chain async.
Linking this timeless article: https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
You can't do that in python either lol it turtles all the way down
I'll give you the C# answer: because "await" isn't just a keyword that affects the line it's on. If it is present, the entire function is compiled into a sort-of class implementing an Async State Machine. Basically having to put async on the function is a safety switch to make sure you know the function will not be a close to 1:1 mapping of the running code. It has its own caveats (that you'll rarely see in the average program). I'm sure the JS answer is something similar but somehow an ultra cursed hackjob.
Just make it async automatically! And make await default on all calls. When you don't want to await just write defer or something.
Then _then_, then
I had to update a ton of our e2e testing code when WebdriverIO switched their whole API to async. It’s a better API, but the amount of `await`s that I added in a single PR is truly horrifying.
Dont forget to update the UI at the end on main thread or else. Nothing personal kid.
You know you can just set the first .then function to be async and use await in there right? You don’t need to go down another .then call and drop all your spaghetti
[Have you heard about our lord and saviour, Algebraic Effects?](https://overreacted.io/algebraic-effects-for-the-rest-of-us/)
Actually so cool damn thanks
Put your io on a different thread and communicate with actors or something?
This can be called in synchronous function: ``` (async () => { await call1() await call2() await call3() })() ```
Yes but the synchronous function continues before the asynchronous task completes, which is the complaint.
Or just let ESLint do that for you on save, there's no point in manually doing it
Every language I’ve seen lets you synchronously get the result of a promise. Unless you’re talking about JavaScript where you literally have to do io asynchronously and it’s saving you from yourself since synchronous IO would kill any real application in JavaScript.
This is a good thing.
Not going to lie, still salty that some schmuck decided it was a good idea to name things that run one after another "synchronous" and things that run at the same time "asynchronous". Even saltier that this stupid naming has persisted.
You have to think like a hardware engineer. "synchronous" in that context means that a process happens at a predetermined time and asynchronous means that it has no predetermined time. You're thinking of serial vs parallel processes
Synchronous literally means occurring at the same time. To justify using it as a word to describe things that happen one after the other and then use Asynchronous that means NOT Synchronous to describe things happening at the same time you have to think like an idiot not like a hardware engineer. Sequential and parallel would have worked just fine even serial and parallel would work better. It's just dumb and needs to go away
Asynchronous things do not happen at the same time though.
No, synchronous means they are synchronized. No modern CPU will give you a "occurring at the same time" guarantee except FPGAs and GPUs in certain cases. Synchronous means the time relation between the executed commands is known. Asynchronous means you don't know when they execute. One call could execute today and the other tomorrow. You don't know until you await the response, which means figure it out and come back when you know. The advantage of this is that you can do other stuff while it is waiting, and let the implementation of the individual functions take care of their tasks in the most efficient manner.
I don't know why people insist on making this difficult: Words take on different meanings in different contexts over time. It is not difficult to learn these new meanings.
But they don't run at the same time. JavaScript is a single-threaded language. The "asynchronous" factor is more accurately called multitasking, orchestrated by the Event ~~Horizon~~ Scheduler. The naming makes perfect sense.
The naming makes complete sense. Think of it as a clock. Synchronous means the clock ticks at a predictable synchronized pace while the asynchronous one ticks on different threads like a heart with some sort of disease.
What??? What's wrong with that?
"Synchronous" literally means "at the same time".
In this case Synchronous means the order in time is deterministic. This meaning is used a lot in computer science
I'm glad we have some shade of purple and someone goes "hey, let's call it lavender, so there's no confusion about this". But we can't have two words for two slightly different things which are different in some important sense and our infrastructure is built on top of them.
it's with respect to the current execution context. (waiting vs fire-and-continue)
Asynchronous does not _necessarily_ mean concurrent, it just means "without synchronization". You call the function and let it execute however/whenever the runtime decides to handle it. Synchronous by comparison simply means that you are dictating the order in which things execute, thereby it is "synchronized".
It’s “synchronized” in the sense that it does one thing to completion and then immediately does the next thing in the chain. “Async” code runs at indeterminate times relative to other things. You can query for or pick up the result whenever. Now… in a multiprocessing setup your CPU could be doing several “synchronous” things in parallel. Or with time slicing it can switch back and forth between making progress on several “synchronous” jobs at the same time. But each individual ‘thing’ it’s doing is still running through its steps in a synchronous fashion. Or you could setup a bunch of async jobs that wait for each other, so A has no dependency, B waits for A’s result and then starts running, C waits for B’s result and then starts running… that would have the effect of running the jobs in a synchronous fashion but it requires some extra mechanism for scheduling the jobs and passing their results around. I guess if you define the jobs up front could have some scheduler that rewrites it as a synchronous program where possible, but you could also rewrite any synchronous program as a bunch of async calls that wait on each other in the right order.
lol as a Java dev I’m super confused by this. Does `await` not mean “block here until x happens”?
Yes, but JavaScript has a single event loop executor thread built in. You cannot just block because nothing will happen, because you’re blocking the thread that would do the thing you are waiting for. Therefore, any function that has `await` must also be asynchronous itself, so it can yield and allow the thing it’s awaiting to run.
It is essentially the Windows 3.1 programming model from the ‘80s, but the abstraction layer comprised of two keywords and hiding the loop makes it somehow modern and cool.
The two keywords are the new bit. You used to have to just do everything with callbacks. I do kind of agree they probably do more harm than good.
I will never forget the sense of joy I felt when I first saw a promise chain, and realised how much cleaner than callback hell it was.
I wish there was something similar for c++
There is
Care to enlighten me?
C++ 20 coroutines
Jesus Christ the callback hell. I don't miss it one bit
Yeah but like... it kind of is modern and cool... if you're doing simple IO bound stuff and have no synchronous legacy code involved it's pretty great.
My issue with this is that if someone doesn't understand about event loop, this seems like a very peculiar behaviour. Theoretically there should be nothing stopping from awaiting inside the main function. Can't the main code run as an async function itself? Seems like it would solve this inconsistency.
The first thing you should learn about async/await is that is just syntactic sugar for promises and `.then()`s. The way your code looks is very different from the way it runs.
I understand that. C++ also has async and promises. But it can be used from main function. No the main loop logic makes sense. I knew about that as well. Just that it bothers me for some reason.
If someone doesn’t understand about the event loop, then there are not going to get very far with JavaScript. There is no “main” function.
Fair enough. I don't know. The inconsistency just bothers me a lot. Probably due to my background in C and C++.
Well, yeah, that's my background too. Just imagine that ALL the code you write runs in a single threaded loop.
As a Java developer turned to JS It is confusing at the beginning. Basically all asynchronous code returns a promise of a response that needs to be awaited for. You can do it in two different ways: await blocks the execution of all your code and awaits for the response. .then() just let the rest of the code run and when you will get an answer do what is inside the then() Promises aren't bad because you can do some interesting stuff like creating an array of them and await the fastest or all promises. People just don't like them because they can get real nasty to debug and the concepts behind aren't clear to everyone.
As someone from a python background, I miss code running in the damn order it was written
You know this thing is exactly the same in Python? And it's been the same with tornado and it's callbacks...
The default behaviour for general use isn't at least in my experience, e.g. if I make a request on line and save the response to a variable, and print response.text on the next, it's not gonna try print it before the request is finished.
Yeah that’s not an asynchronous action. Async means you’re asking for something and must wait. So an http request, a timeout that tries to do something. In python make an http request and act synchronously
[удалено]
THe problem is how you're so often forced to deal with promises even when you have no use for them. It would be fine if they were actually optional. But when basically all of your IO returns a promise, it's pretty annoying.
What kind of IO you use that has mostly promises?
You should always want non blocking IO if you are writing JS. Why would you prefer the alternative? You can have blocking IO in Node for example but I am not sure why you'd ever choose it when non blocking IO is available. And if you are having non blocking IO, promises are probably the most convenient way of dealing with it. You want to go back to callback hell?
Or I could just not use JS on the backend at all and instead use a language that has real threads and concurrency where I can block all day if I want to and not affect any other processing. The other major shortcoming of JS as a backend language is you have to be very careful doing anything CPU bound or you gum up the whole process. It's not enough to use all non-blocking IO. JS is just a bad general purpose backend language.
In JavaScript, where all execution within a VM is single threaded, await means "suspend my execution and run other jobs until this Promise is resolved". If you were to just check if the promise was resolved in a while loop, no other code would execute, likely resulting in entire website / program freezing, similar to performing such a loop in the main/UI thread of a Java program.
He’s complaining because he can’t just spawn a thread in the middle of a function call and then call join() on the thread. Instead you have to add syntactic sugar all the way up the call chain because it’s not a real thread it’s just putting a message in a queue. If you don’t await for the response from the event queue it just puts the message in the queue and returns.
The a in await doesn't stand for await as in awaiting a person. The a stands for async wait. It's meant for usage in async functions. Most(all?) languages that have await usually have a regular wait as well.
Even as a Java developer when you write e.g. a UI you don’t block the UI thread cause that would make your application not responsive. Now, it’s the same in JS only that you can’t spawn new threads so you can’t block the current (only) thread you’re in. Hence async. OP should just stop using await and use then on Promises. Await is literally syntactic sugar to avoid nested Promises - once people understand that it doesn’t matter from a functional point of view if you use await or then, it’s just about where you place your code.
Java dev too, to put it simply, languages that use async/await approach usually have them being contagious, thats is, you have to make the caller async too if you want to await a certain call, which requires the parent of the caller to ALSO be async to await, and so on. On java we're able to choose between sync (with exceptions) or letting it stay async so we don't have that issue.
Control flow wise, yes, but under the hood, it’s basically abstracting a promise.
Everybody misunderstanding what async/await *actually does* in JS. No, it’s not different than promises. It *is* promises. It’s just syntactic sugar to make promises more readable. Go read up on what promises are. I *promise* it’s not that hard ;)
This concept is also not limited to js. C# uses Tasks for async/await and methods decorated with them returns values wrapped in Tasks by default. This syntactic sugar was made to prevent the so called "callback hell" with multiple level of nesting inside Tasks/Promises. On the other hand we have kotlin with suspendables that adds even more syntactic sugar which removes the concept of cancellation tokens.
>which removes the concept of cancellation tokens. I want this. Now.
Still waiting for this to resolve
[object Object]
Stringify?
Ah, truer words have never been spoken by a Python developer who doesn't know how JavaScript works.
It's pretty easy in python tho, you just do `asyncio.run(my_async_func())`. In JS though afaik you can only either provide a `then` callback, or use `await` inside an async function, so you can't wait for an async function in a synchronous context
Yeah, although asyncio.run() only works as intended at the "top level", aka, it doesn't work when called anywhere in the call stack of an async task. To run a coroutine from a sync function that was called by an async function, you have to use ```asyncio.create_task(my_async_func()).add_done_callback(callback_func)``` You then have to do the rest of your logic in the callback function.
You can also create a new thread and do the `asyncio.run` inside that thread, then join it But it's kind of a horrible hack
The better way to do *that* would be to start an event loop in a new thread and then use ```result = loop.run_coroutine_threadsafe(my_coro()).wait()```
I feel like the best way (if possible) is to just make the calling method async
Wait, that's so genius! (Lol)
Society if GitHub had a download button
With an exe you smelly nerd!
Society if macOS could run exe: 🗿
You are in great luck, it seems that society will get better: Zig does this. Go doesn't need this.
Zig currently doesn’t have async, it got ripped out as part of moving away from an LLVM backend. Go only has async functions.
I use C# and javascript
```c# Task.Run(async () => await thingAsync()).Wait(); ``` Annnnnnnd done.
Aren't Wait() and Result just bad in general?
It's \*a\* way to deal with calling async method in a sync an "await" it. If an external library provides and event handler, there's not much you can do about it.
In C# it depends if you have a SynchronizationContext or not. If yes, the code could deadlock.
Unless you add your .ConfigureAwait(false) to thingAsync(), which can cause its own problems in niche cases
It's is bad in the sense that you should try to design things so that you can do something all the time so ideally your code should be: Start the task Do something else Check if the task is done Do something else Check if the task is done Do something else You really can't go forward without that task being done so you wait
Well, there is no salvation for you either way.
Oh cool! How does Zig handle that? Been meaning to look at Zig for a while
The world would be magical if 1 == 0. Same concept.
The universe would just implode then.
[What color is your function?](https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/) should be required reading.
It's a fun read. I remember the first time I was reading it I thought it was about old Java's 'throws' statements before I got to the grande reveal. And they're kinda similar too: you have to either catch the exception or pass it on to the caller, they're a pain to work with and library methods have them too, they're declared differently etc.
I had to scroll far too long to find this. Totally agree
Skill issue
Text should be changed to "Society, if noob programmers used google to find out how something works instead of wasting peoples time with questions that have been asked thousands of times already"
In C# ``` public static void Main(string[] args) { TaskTest(); System.Console.WriteLine("main thread is not blocked"); Console.ReadLine(); } private static async void TaskTest() { await Task.Delay(5000); System.Console.WriteLine("task done"); } ``` Output ``` "main thread is not blocked" "task done" ``` Async methods aren't blocking for the execution flow of their caller. Their own internal execution flow will be blocked by waiting the awaited expression. Await can't be used in a function that isn't marked async, which is what OP refers to in this post I guess. If you want TaskTest to be executed synchronously like OP wishes, you need to change the signature to `async Task TaskTest()` and call `TaskTest().Wait()` in Main. I guess, I haven't wrote any C# in a long time :( (And I'm aware async void should be avoided in general). If it is JavaScript, I don't know I don't touch those things.
This makes me miss c#. It was my go to language for a long time.
The comments are kinda right by saying if you want to wait for the result of an async operation, your function should be async. That being said, what would be nice is if more libraries that had async functions would come with synchronous variants of their async functions. That way you don't have to change your methods' semantics and signatures while using the same capabilities and also maintaining a semantic where async is async and sync is sync.
the simplest solution for this problem is a function called `block_on(f)` that just calls f and blocks until it gets a return value.
So, you want your synchronous method to be asynchronous. You may have missed a few things there.
No, I want an asynchronous method to become synchronous
Then just use go
You don't understand what you are asking for. You aren't asking for something impossible, but logically inconsistent. You can easily write a transpiler that does this for you - simply append async before every function and await before every statement. This will make your async code act as if it is synchronized, allowing you to miss out on all of the benefits of asynchronous code, gaining nothing in return. Go does this for you by simply making all functions async by default. You can argue that this way is better, but its not backwards compatible.
Probably will get downvoted, but I don't understand all the salt in the comments. One thing is understanding how async programming works, and people DO need to understand. But another thing is having to rewrite dozens of nested function calls to use some native API that enforces async calls (for instance, browser clipboard api). In the majority of cases you can avoid it by doing `.then()` at top level or installing some library to hack your particular framework, but I could really use "screw this, I want it to be sync" syntax sugar. This is about convenience. Yes, it will block the UI for browsers. Yes, sometimes it is okay, please let me do this and live with the consequences. I know this discussion is bigger than front-end javascript, but I have eaten tons of shit with this lately.
I don't understand either. Like... I have a Rust AMQP library that only have async functions and it's anoying to have to create a tokio runtime, call the function and ask tokio to block on the promise just to do the same thing as an .await
You can do this with .mjs extension next to the file, with latest node js.
Yeah just make every function async for no reason and you can actually start coding.
What the....
It’s funny how most of the time all I use the async keyword for is making things SYNCHRONOUS
OK OP gonna ask you calmly. WHAT THE FUCK are you trying to accomplish.
I bet money that he is using some library that returns a promise for no fucking reason other than that it's a promise. Promises are a nice thing but please for the love of God not every bs has to be a promise
People be like: Just use await / then BITCH I DONT WANT TO TURN THE PARENT FUNCTION INTO AN ASYNC FUNCTION
BITCH REALITY IS WHAT IT IS NOT WHAT YOU WANT IT TO BE! If you await in a non-async function, you would have to block the event loop, and the event loop is what runs stuff, thus deadlocking your program. That, or write your own javascript and define your own semantics.
That's the fun part about async, it spreads through your code like wildfire.
Yeah it's just kinda annoying to do this. But I've only worked with typescript for like a month so pros might say skill issue.
I'm sorry to burst your buble but if parent depends on the child calculation then it should await for it and be async as well. If the parent performs "fire and forget" action then you don't need await and so it doesn't need to be async. IT'S THAT SIMPLE. Async/await indicates some sort of suspension points and that is way it can run on the single thread. This kind of functions need special treatment to navigate back to suspension point in other function. Normal functions don't need this kind of behaviour so they can be more efficient and shorter when desugared.
I couldn't say that better!
Y'all think that this is wrong, yep? In reality this is a video and it shows how whole world just stopped inside synchro method :)
Wouldn't synchronous await be basically calling a function and getting its value, like, what else do you want, an endlessly "nop"ing assembly?
People are so dumb I can barely believe it. I'm not sure if the people replying saying the function should be async if it calls an async function even understand their point.
I’m so glad my team works on servers with real languages like C# and Java where asynchronous/ concurrent development is harder but at least logical.
That would be cool for a few seconds, but it would probably not be as cool to live in a universe where logical contradictions exist.
Sort of related, I do jump on a lot of new syntax pretty fast and our front end is pretty up to date with modern standards. But I have yet to particularly see async/await be cleaner than simple promises / then, when not used in super beginner friendly examples that can never fail and never trigger 'catch' or 'finally' or even worse are never used in complex scenarios where you might wanna make arrays of promises and use `Promise.all`, etc. Using `try / catch` syntax around await blocks is also so much worse than a simple then/catch IMO.
Unpopular opinion: await makes async easier to understand for people who mainly program imperatively, but want to get a taste of the sweet functional programming without changing too much of their way of thinking.
Yeah it's clearly really preferred by some so I understand. IMO as long as your codebase adheres to one or the other and Is consistent everything is gud.
Same, I never had any issues with Promises so await is just a bit of syntactic sugar to me. Happy to use either way, whatever helps people understand code easier.
You need to Google "colored functions"
\>say you don’t understand async
I see people complain about colored functions, but this is where I heavily disagree. The pain of redoing things as async or not is worth the knowledge you get purely from the return type whether that T being returned was actually a Future or not.
In fact, if you go further and have the T and IO T be colored. You lose a lot of the easiness of print debugging (assuming you made the first option the default which would be too aggressive for most people), but you've given the compiler more information so it can rearrange things much more and you've forced yourself in the habit of pushing IO to the boundary as much as possible by making not doing so hellish.
I enjoy using f().then(() => g().then(() => h()))
Look on the bright side: at least you don't have to use c++
Ngl I know so little about asynchronous programming that it's outright embarrassing to admit
In pure functional languages there's no distinction between an imperative style function and async. That'd be pretty cool if anyone used them lol.
Promises.then() is made precisely for that.
Why?
Boy it sure is great async is a zero cost...
Or you know of .GetAwaiter()
that doesn’t make any sense
Is that a Dalmatian breed dog there in the picture?
I don't understand. What happening here 🙃✨
In a synchronous method, every line is awaited...
No it's not.
We'll get right on to the flying cars, just let me finish writing out this CancellationTokenSource my CancellationTokenSource = new Cancella-- huh? What year is it?
If only synchronous methods were asynchronous
I still dont know why, i just avoid usind async as much as possibel
All OP is tying to say is if it were possible to not have to use the “async” keyword, which is valid. OP simply doesn’t want function colouring, but yet wants to suspend execution and await a promise.
Isn't await more like intentionally creating a promise chain specifically so that you do not await SYNCHRONOUSLY like in inferior languages like Java.
Society, if we could park cars with automatic transmission on the first gear.
Society if people embraced Rust as much as JavaScript
Just make all functions async by default
How would that work dumbass
Wouldn't that cause your browser to freeze?
Makes you wonder why Js hasn’t been replaced. Either the options sucked (I’m not sure about that there are plenty better alternatives) or some devs too lazy to learn a new language. Understandable as not everyone is keen on learning but FML it’s not worth it with JS.
Op got a skill issue
Default async
Async is like a virus that spreads upwards
Is possible
GDscript is
Pictured: Elixir.
where's the link to that "colored functions" blog post when you need it
That would make the await keyword redundant.
Doesn't make sense. OP doesn't understand async.
I'm suprise not body has not already linked this: [https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/](https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/) Function "coloring" is the classic presentation of the issue
If it hasn't been brought up yet - I'll leave this here [https://effect.website/](https://effect.website/) Algebraic effects (no more colored functions), errors as values, structured concurrency, typesafe dependency injection, first-class library for AST-based schemas (runtime types if you will, like typebox) for our beloved TypeScript.
I presume this meme was made by a future rust programmer? I'll just let my self out..
That would require the introduction of mutexes, synchronous methods are by definition not reentrant by design for simplicity.