5 ms·
Are you sure? How would the JavaScript functions execute simultaneously on a single thread? Async is about interleaving computations on a single thread.
by Buttons840 7y ago
Are you sure? How would the JavaScript functions execute simultaneously on a single thread?
Async is about interleaving computations on a single thread.
- ilikehurdles 7y agoAsync doesn't have to be single-threaded generally. JavaScript is limited to a single-threaded model, but in other languages (like clojure), futures are tasks run on some other thread. I don't use rust and this article doesn't make any mention of threads so I'm not really sure what's going on here.
- Rusky 7y ago> futures are tasks run on some other thread. This is usually false, in Rust and elsewhere. Futures are tasks that run on whatever thread is scheduling them. They are an even lighter-weight version of green threads/fibers/M:N.
- pimeys 7y agoBut only if you await them in that thread. If you `spawn` them, they can be executed in another free thread; although you'll miss the return value in this case. So for people new to async/await in rust, how a web server usually works: Request/response future is spawned to the runtime, and a thread decides to take the future for execution if the runtime uses multithreading. Inside of this request/response future whatever futures are .awaited will continue the execution in the same thread when ready. Users can also spawn futures inside the request/response future, which might go to another thread. The result of this future is not available for the spawning thread. Some executors have special functions, such as `blocking` that will execute the block in another thread, giving the result back to the awaiting thread when finished.
- ralusek 7y agoThey're asynchronous tasks, there would be no point in using promises with synchronous tasks. So we're not talking about simultaneous execution of functions that are making use of the single thread, we're talking about serial execution of functions on a single thread which are basically doing nothing more than scheduling an asynchronous task and not bothering to wait for the result. Think of it this way. I have 3 letters I need to send, and I'm expecting replies for each. A single threaded, synchronous language, would basically send the first letter, wait for the reply, send the second letter, wait for the reply, then send the third and wait for the reply. In JS, you're still single threaded, but you just recognize that there is no point in sitting around and waiting before moving onto the next item. So you send the first letter, and when it would be time to wait, you continue executing code, so you immediately send the next letter, and then finally send the 3rd. How they're scheduled simultaneously on a single thread is exactly what makes JS so fast for IO. Once it starts making an http call, db call, disk read, etc, it will release the thread to begin execution of the next item in the event loop (which is the structure JS uses under the hood to schedule tasks). So what really happens is when we call asyncA(); asyncB(); JS will go into `asyncA`, run the code, and at some point it will get to a line that does something like "write this value to the database." This will be an asynchronous behavior, that it knows will be handled with a callback or a Promise, so it will immediately continue execution of the code. So now it pops out of executing `asyncA` and executes `asyncB`, meanwhile the call to the DB has gone out and we don't care if it has finished, we'll await both of these when we need them.
- Rusky 7y agoJavascript has two differences that contribute here: * First, it runs the callee synchronously until the first await, which can fire off network requests, etc. * Second, continuations are pushed onto queues immediately- the microtask queue that runs when the current event handler returns, for example. Rust does neither of these things: * Calling an async function constructs its stack frame without running any of its body. * Continuations are not managed individually; instead an entire stack of async function frames (aka Futures) is scheduled as a unit (aka a "task"). So if you just write async functions and await them, things behave much more like thread APIs- futures start running when you pass a top-level future to a "spawn" API, and futures run concurrently when you combine them with "join"/"select"/etc APIs.
- roblabla 7y ago> * Calling an async function constructs its stack frame without running any of its body. This is actually possible to do by using async blocks instead of async functions. E.G. you can write this: fn test() -> impl Future<Output = ()> { // Run some things directly here println!("I am running in the current frame"); async { // Run some things in the await println!("I am running in the .await"); } }