CompletableFuture.get() equivalent in javascript Promise? - javascript

I recently programming in Typescript/Javascript from JAVA 8. As soon as I encountered async/await, it reminded me of CompletableFuture. In java, regardless of the return type of a method, I can call someMethodReturningFuture.get() inside a method and can block the execution at will. But in JavaScript why do we need to declare a method as async when we want to block on some other asynchronous method using await? May be there is something so wrong that I am believing till now about Java/CompletableFuture.

Because JS has a synchronous execution model. The resulting behaviour is often described as "single threaded". For sure you could block that "single thread" to wait for the resolution of a promise, but that would block anything², a behaviour that you probably don't want, and thus it is not part of the language.
²: including browser rendering / reacting to the user, as well as the promise resolution itself ...

Related

volatile variable error in Chrome's JS engine?

According to my understanding, in JS there are not race conditions for synchronous code. That is, during the execution of a function variables should only be accessed by 1 executing thread.
However, I have run across this:
In this image you can observe how the predicate of the if statement in line 186 evaluates to true. The code inside the if statement contains only a return statement. Hence, there is no way the thread could have escaped the if statement.
Some context into what sort of functions are calling into this:
This is a service worker MV3 extension.
A number of function stacks are awaiting for the closePromise. Once the close promise resolves, my premise is that the first "thread" to call __innitialize will pass the if statements into the executing thread. When the next "thread" calls __initialize, then the first one would have changed the state to INITIALIZING, thus he would enter the first if statement, and await for the initPromise.
I may not provide anymore than this snippet due to company policy.
(V8 developer here.)
I agree that concurrent modification can't happen in JavaScript. The other obvious explanation (that the JS engine incorrectly checked the condition) would be a severe (and pretty obvious!) bug.
But without further information or a repro, it's hard to say anything for sure. For instance, if this is an embedder-provided object and .__state is an intercepted property, then anything could happen, and it's entirely outside of V8's control. You also mention "sleeping" in the comment: sleeping (and awaiting) are interruptions of synchronous control flow, so if you have such things in your code, that could also explain why things appear to "magically" change after such a point.

Async/Await in Javascript vs C#

I am trying to understand asynchronous programming and came across async/await keywords. I got stuck in understanding use of async/await keywords. I actually looked in two programming languages, JavaScript and C# and found much differences in use of async/await keywords in both languages.
For JavaScript it says:
Async/await makes your code look synchronous, and in a way it makes it behave more synchronously. The await keyword blocks execution of all the code that follows it until the promise fulfills, exactly as it would with a synchronous operation.
Link: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await#:~:text=Async%2Fawait%20makes%20your%20code,would%20with%20a%20synchronous%20operation.
So, its saying that async/await will make the execution synchronous.
For C# it says:
The async keyword turns a method into an async method, which allows you to use the await keyword in its body.
When the await keyword is applied, it suspends the calling method and yields control back to its caller until the awaited task is complete.
Link: https://learn.microsoft.com/en-us/dotnet/csharp/async#:~:text=The%20async%20keyword%20turns%20a,used%20inside%20an%20async%20method.
So, its saying that use of async/await will make the code execution asynchronous.
I would like to ask, is there really a difference between the use of async/await keywords in JavaScript and C#?
Or,
Is something missing in above statements?
Javascript docs says 'it makes your code look synchronous', it doesn't say 'it makes your code synchronous'.
In terms of behavior there's no difference between javascript and c# in async/await.
async keyword denotes that there's an asynchronous operation in this method.
await keyword helps making a CPS (continuation passing style) coding into a code that looks like synchronous. CPS is similar to using then() in javascript after promises or using ContinueWith() in C# Tasks.
Any code before 'await' is running synchronously under current thread. When execution reaches to 'await', the awaited operation starts under a new thread (not necessarily a new thread, but suppose a new thread), hence an asynchronous operation starts, and current thread is freed. When the awaited operation ends, execution returns to the point it left off in the 'await' keyword and continues.
The internal working of javascript and C# are different.
Javascript is event-driven. There is a main event loop and a single thread in javascript. When the awaited operation finishes, an event is raised under the hood and the main single thread continues executing of the async function where it was left off.
In C# there's no event loop or a single thread. We either should use manual threads and explicitly wait and join them after they did their job, or we should use something like async/await that manages thread and continuation management on behalf of us. Using TPL which C#'s async/await internally uses that, continuation of an async code is passed to another task using callbacks.
Anyhow, 'await' keywrods turns a complicated chain of nested then() -js- or ContinueWith() - c#- into a simple beautiful code that looks like a normal -synchronous- code.
function doSomethingCPS() {
asyncOperation1()
.then(r1 => { consume(r1); return asyncOperation2() })
.then(r2 => { consume(r2); return asyncOperation3() })
.then(r3 => { consume(r3); })
}
async function doSomethingAsync() {
var r1 = await asyncOperation1();
consume(r1);
var r2 = await asyncOperation2();
consume(r2);
var r3 = await asyncOperation3();
consume(r3);
}
The two codes are equivalent. But, it's clear that the latter is much more simpler and easier to read.
There's a difference between thread management in javascript and c#.
As it is said, in javascript there's only one thread. If it blocks for any reason, the page will block. It's when browsers show 'The page is not responding' or 'There is a javascript code in this page that blocks the page' message after 20-30 seconds.
In HTML5 worker threads were introduced that helps to employ a real separate thread. It's another topic though.
You might ask if there's only one thread in javascript, how on earth can an asynchronous operation work that is said to work under another thread?!
Good question. In javascript although there's only one single thread, there are objects that natively use separate threads. timers - setInterval() and setTimeout()-, XMLHttpObject() and fetch() are good examples in this regard. Thus, in javascript we indeed can have asynchronous code.
One final point is the way C# uses threads. In C#, async/await works using a library named TPL (Task Parallel Library). There is a Task class at the heart of TPL that resembles an asynchronous task.
The real point we should know is that, a Task is equivalent to an async operation, but it does not necessarily mean a Task uses explicitly a separate thread. There's a task scheduler in TPL that controls internal threads usage. If a Task's job is quick, using a separate thread wastes resources, so the task will run under current thread.
The only thing we should know is that a Task is a logical unit of asynchronous code. In fat, Task is introduced to free us of manually thread management which is nearly a low-level code.
Using async/await we are rid of all boilerplate code that are required under the hood to provide asynchronous code. We can focus on our business code instead.
I am not familiar with JavaScript but this statement:
Async/await makes your code look synchronous, and in a way it makes it
behave more synchronously. The await keyword blocks execution of all
the code that follows it until the promise fulfills, exactly as it
would with a synchronous operation.
Sounds pretty much applicable to C# async/await. For both cases your code looks like you execute it synchronously and your execution is sequential. Because in C# when you have code like this:
// ...
await FooAsync();
Console.WriteLine("Await has returned the execution");
It seems as if your execution thread were running FooAsync, and then, the same thread is calling Console.WriteLine. Whereas in reality when the execution thread hits await, it does lots of things behind the scene. Here's a good article about it. But in most of the cases,
When the await keyword is applied, it suspends the calling method and
yields control back to its caller until the awaited task is complete.
The thread that were executing your code will go about his business. And then proceed with Console.WriteLine when FooAsync is complete by another (or the same) thread.
This behavior is enormously helpful when you work with UI threads like in WPF or WinForms applications.
For example, FooAsync is a very heavy method. It does lots of calculations and takes a lot of time to complete. But you're running your code on UI and when a user hits a button, the underlying code is executed by the UI thread. So if you'll be running and waiting FooAsync synchronously like this:
FooAsync().Result;
Your UI would be "freezed" and the user would demise you.
So when you go
await FooAsync();
UI thread "asks" TaskScheduler to run FooAsync by whatever available thread. After the Task is completed, TaskScheduler tries to execute next line:
Console.WriteLine("Await has returned the execution");
by the UI thread again,
exactly as it would with a synchronous operation.

Why 'await' requires 'async' in function definition

I'm currently learning Dart, but this is also applicable to what's going on in the JavaScript world right now, and it seems like C# also uses the same pattern.
In Dart, any function that uses await must itself be labeled asynchronous through async as follows:
import "dart:html";
main() async {
var context = querySelector("canvas").context2D;
var running = true;
while (running) {
var time = await window.animationFrame;
...
}
}
This does not make sense to me. If a function is waiting on an asynchronous function to complete, is it not then considered blocking? Why do JS and Dart require it to be labeled asynchronous? Would it not be the opposite?
To me it would make far more sense if the calling function must use the async keyword if it calls any function that also includes it in its definition. In this pattern, await would be used to convert asynchronous functions to synchronous ones.
This way would also avoid duplicate functions, since right now, libraries seem to always have func() and funcSync() or funcAsync().
The basic semantics of async/await are the same across F#, VB, C#, Python, Dart, Hack, and JavaScript. So I think this question has sufficient answers from other languages. But since it has been reopened...
If a function is waiting on an asynchronous function to complete, is it not then considered blocking?
No. Think about it this way:
"asynchronous" means "does not block the calling thread".
"synchronous" means "blocks the calling thread".
In an asynchronous method/function, the method/function can be paused at the await points, but it does not block the calling thread while it is paused. The function runs serially (one statement at a time), but asynchronously (without blocking the calling thread).
To me it would make far more sense if the calling function must use the async keyword if it calls any function that also includes it in its definition.
That's how it already works... await consumes promise/future/task-returning methods/functions, and async marks a method/function as capable of using await.
This way would also avoid duplicate functions
This is not possible with historically-blocking imperative languages. A method/function either blocks the calling thread until it is complete, or it does not. It is either synchronous or asynchronous.
There are some interesting alternative approaches to async methods/functions, though:
Go is not historically blocking; you can think of it as a language where every method/function is potentially asynchronous; doing this in any other runtime would be disastrous, but Go avoids those problems by implementing a strict goroutine system with message passing - no shared memory or threads allowed.
Another example are pure functional languages, where Future is just another monad and requires no special compiler support for async/await keywords.
In Dart async indicates that the code containing await needs to be rewritten.
async/await is just syntactic sugar for the Future.then() base API, and the code is rewritten to this canonical Future based form, before it is compiled and executed.
Therefore await doesn't make code blocking.
There are also other supported markers like *sync and *async for generators.
See also
- Dart async/await internals
- https://www.dartlang.org/articles/language/await-async
I'm not sure what your question has to do with C# but await is a most unfortunate keyword choice in C#. await is more understandable if you read it as resume after or even yield then resume after. When execution encounters await, it suspends the current function, returning to its caller. Once the Task being waited on is done, execution resumes after the await when the caller needs the result (from an await expression of its own).
This is a fundamental misunderstanding of what's going on "under-the-hood", I'm assuming the javascript async/await implementation mirrors (at least conceptually) that of the .NET world (which originated in F#).
Essentially:
A "unit of work" "token" of sorts (in C# a Task in JS a Promise) represents a completion of a task with an option of returning a value.
An "asynchronous" method is marked with async, to indicate to the compiler/interpreter/runtime whatever, that this method will return said token, and will likely consume some as well.
The thingamajig running it all, will (in C#'s case), rewrite the code on the sly to essentially do the following:
Start async method
Do standard normal code
Encounter "token" providing method
Call it, grab token
Setup a place the code can jump back to later
Is the token complete? If so, carry on, If not, set a callback to have the runtime come back to this place when it does
In this expanded context, the keywords make sense:
async(hronous) - A method that does some task that can take an indeterminate amount of time, that can be waited upon.
await - Indicates that instead of just grabbing the token from the async method and doing nothing with it, that you actually want to set up all this ceremony around listening out for when the work is done, and carrying on afterwards.
tl;dr
Just think of async and await as invisible callbacks, async indicates when something can be listened out for, and await is what actually does the listening.

Why is the split method for Strings executed synchronously in NodeJS?

I'm new to NodeJS and am having a little trouble understanding what types of actions/tasks are executed asynchronously vs. synchronously. The specific example that I was working through was splitting a string.
I was trying to count the number of new lines in a block of text and then print that out. The below example worked. However, I'm not entirely clear why. My basic (and likely flawed) understanding is that anything that takes time is executed asynchronously (e.g. I/O), but I don't know what types of actions count as "taking time". Does the Split() method "take time"? It has to loop through the contents of a string, and if the string is abnormally long, this could take a while, why does this execute synchronously then or is it just that the split method blocks?
My question here is specific to the split method, but if anyone could also talk about or point me in the direction of some documentation that explains what gets executed synchronously vs asynchronously, it'd really appreciated!
var array = "test\nstring\nexample".split("\n");
console.log(array.length-1);
Most operations in JavaScript itself are synchronous. The exceptions include the obvious ones such as setTimeout(), setInterval(), requestAnimationFrame(), etc. Also just because you pass in a callback does not mean the function is asynchronous (for example see some of the array methods, like array.forEach(), array.map(), array.filter(), array.some(), etc.).
Node.js (core), which builds on top of JavaScript (via the v8 engine), adds its own synchronous and asynchronous methods. However fairly early on it was decided to distinguish between the two by way of an easily visible Sync suffix to functions that perform synchronously. However, similar to JavaScript, there are some exceptions (e.g. require()). It should also be noted that userland modules (on npm for example) may have their own convention (or none at all), so for those third party modules you will need to read the documentation to be sure of the behavior of their exported functions.
Essentially JavaScript is single threaded. The best advice is to assume it is single threaded unless something suggests otherwise.
Functions that aren't synchronous tend to accept a callback parameter to be executed. Examples of these would be a jQuery.ajax call or the setTimeout function.

Javascript Promises library to make "long-running-code-non-blocking-UI" in browser?

Update
this an update to the question below and should help finding an answer
Taking up the answer from torazaburo who also quoted part of the prominent Javascript Promise/A+ definition I want to update the question here.
The Promise/A+ specification suggest in point 2.2.4 this:
onFulfilled or onRejected must not be called until the execution
context stack contains only platform code. 3.1.
and further explains
Here “platform code” means engine, environment, and promise
implementation code. In practice, this requirement ensures that
onFulfilled and onRejected execute asynchronously, after the event
loop turn in which then is called, and with a fresh stack. This can be
implemented with either a “macro-task” mechanism such as setTimeout or
setImmediate, or with a “micro-task” mechanism such as
MutationObserver or process.nextTick. Since the promise implementation
is considered platform code, it may itself contain a task-scheduling
queue or “trampoline” in which the handlers are called.
The very issue I look forward to find with this question is having as the crucial point that Promise implementation Javascript code is itself considered platform code and allows to not yield to the eventloop inbetween resolving subsequent promise via calling the onFulfilled onRejected functions associated. This is good in Node.js(server) as it avoids unnessary relinguishing back to the event-loop (leaving the execution stack), but also causes the challange in a Browser that since the execution stack is not exited in between resolving a potentially large number of Promises (which themselves can generate new Promises). Not leaving the execution stack and yielding to the event loop is causing in a Browser the undesired (blocking script warning/problem).
The "trampoline" task-scheduling of the Promise implementation which causes this needs however not necessary refrain from handing back the execution to the Javascript event loop from time to time. Such a feature would allow for using Promises for heavier tasks. Such an implementation for Promises for "long-running-code" is searched/asked for in this question.
Clarification: The "excessive lenght" is not the individual length of the onFulfilled function, but the joining together several those functions/callbacks as result of the Promise resolving process (when done in such a "trampoline" way). I am already aware that if one individual onFulfilled funciton is too long, this cannot be helped in any way by using any sort of Promise implementation.
The deal here is that the subsequent resolvement of x promises (within one excecution stack and hence without handing back to the Javascript event loop) can provoke an excessive length duration of Javascript code execution. This, when in a Browser is bad (because of blocking).
The question
In Javascript, Promises allow to deal with asynchronous programming tasks. Great!
There are already some implementations and libraries arround Q, WinJS or when.js to name just a few.
Having looked at then I see that they tackle some of the "special things" in Javascript asynchronous programming challanges.
Normally I perceive them to do this for promise resolution
Go to the internal list of promises
Check if the promise is fullfilled + run all the associated (via then(onFullfilled,onReject)) functions.
(in some cases we are done here)
(in other cases there will be still "pending" promises)
This case (4) is because to have them (the remaining promises) fullfilled would need the current Javascript Code (which is this very code for promise resolution) to stop running and allow JS event loop to happend (i.e asynchronous things like XHR-requests, or User-UI-interaction). To make this (4) work, the promise resolution normaly schedules a recall (i.e. via setTimeout/setImmediate) and continues after the event loop ran and hence maybe some of the "pending" promises have been settled (=rejected/fullfilled).
My worry is that the step 1 and 2 could be runnning for quite a some time, only releasing execution to the event loop in case it seems indicated to settle some of the "pending" promises. While "okay" in some cases (i.e. on the server/Node.js) it is quite problematic in a browers, because even though it was no problem to release execution to the event loop and have the UI not-blocking, this is not done in the implementations of promises I have seen.
My question therefore is:
Do you know a promise implementation (Javascript Promises library) that cares for the aspect:
to make "long-running-code-non-blocking-UI" in browser?
which would mean that the promise resolution would voluntarily release execution back to the event loop so that CSS animations, user input, mouse interaction, does get enough attention and that there will be no "Warning: Unresponsive script" message.
Any compliant promises implementation will not run the then functions synchronously, but rather only at the next tick. Therefore, your worry that "step 1 and 2 could be runnning for quite a some time" is unfounded.
From the Promises/A+ spec:
onFulfilled or onRejected must not be called until the execution context stack contains only platform code.
Here "platform code" means engine, environment, and promise implementation code. In practice, this requirement ensures that onFulfilled and onRejected execute asynchronously, after the event loop turn in which then is called, and with a fresh stack.
In other words, your formulation under 2) is incorrect. The promises implementation does not "run the associated functions", it schedules them.
This cannot help you--indeed there is no way to help you--if a handler itself is "long-running" code.
I think the solution could be to parse that long-running JavaScript code for example with https://github.com/NeilFraser/JS-Interpreter.
It will make the code be even slower, but you could specify the priority:
const myInterpreter = new Interpreter(myCode);
function nextStep() {
if (myInterpreter.step()) {
window.setTimeout(nextStep, 100/speed);
}
}
nextStep();

Categories