Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 473
Hem Bhagat Avatar asked May 20 '21 14:05

Hem Bhagat


People also ask

What is the difference between node JS async model and async await in net?

One difference is that Node. js is asynchronously single-threaded, while ASP.NET is asynchronously multi-threaded. This means the Node. js code can make some simplifying assumptions, because all your code always runs on the same exact thread.

Can I use async await in JavaScript?

The await operator is used to wait for a Promise . It can only be used inside an async function within regular JavaScript code; however it can be used on its own with JavaScript modules.

What is difference between async and await in JavaScript?

The async keyword is used to define an asynchronous function, which returns a AsyncFunction object. The await keyword is used to pause async function execution until a Promise is fulfilled, that is resolved or rejected, and to resume execution of the async function after fulfillment.

When should I use async await JavaScript?

Async/Await makes it easier to write promises. The keyword 'async' before a function makes the function return a promise, always. And the keyword await is used inside async functions, which makes the program wait until the Promise resolves.

What is the difference between await and async in JavaScript?

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.

What is an async function in JavaScript?

An async function is a function that is declared with the async keyword and allows the await keyword inside it. The async and await keywords allow asynchronous, promise-based behavior to be written more easily and avoid configured promise chains.

What is the use of await function in JavaScript?

Await function is used to wait for the promise. It could be used within the async block only. It makes the code wait until the promise returns a result. It only makes the async block wait. Notice that the console prints 2 before the “Hello World”. This is due to the usage of the await keyword.

Can you use await in a non-async function?

If we try to use await in a non-async function, there would be a syntax error: function f() { let promise = Promise.resolve(1); let result = await promise; // Syntax error } We may get this error if we forget to put async before a function. As stated earlier, await only works inside an async function.


2 Answers

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.

like image 198
Mansoor Omrani Avatar answered Oct 26 '22 03:10

Mansoor Omrani


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.

like image 3
Gleb Avatar answered Oct 26 '22 02:10

Gleb