admin管理员组

文章数量:1202187

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: :~: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: :~: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?

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?

Share Improve this question asked May 20, 2021 at 14:47 Hem BhagatHem Bhagat 4134 silver badges16 bronze badges 5
  • 7 So, its saying that async/await will make the execution synchronous. That's not what it says. It says that it makes the code look synchronous. – Robert Harvey Commented May 20, 2021 at 14:50
  • 2 If you read between the lines, you'll see that they're both saying the same thing. "The await keyword blocks execution of all the code that follows it until the promise fulfills" is exactly the same statement as "When the await keyword is applied, it suspends the calling method and yields control back to its caller until the awaited task is complete." – Robert Harvey Commented May 20, 2021 at 14:52
  • 1 await does not block the thread. Other operations can still happen elsewhere in the meantime (like a setInterval, for instance). The line below await however, will be executed after the await completes. It does not make an asynchronous operation synchronous, it's just some awesome syntactic sugar that solves Promises callback hells. – Jeremy Thille Commented May 20, 2021 at 14:54
  • async/await behaves similarly in C# and JavaScript. In fact, C# Task and JavaScript Promise are ideologically similar. There are some differences in how they utilize resources (threads) for async/await operation (because C# is multi-threaded and JS is single-threaded) and other differences like controls over the operations (e.g. delayed start, stop etc). However, they provide the same experience from the coding / engineering point of view. – Yeldar Kurmangaliyev Commented May 20, 2021 at 14:55
  • In JavaScript it says, The await keyword blocks execution of all the code that follows it until the promise fulfills, exactly as it would with a synchronous operation. And in contrast to that in C# it says, When the await keyword is applied, it suspends the calling method and yields control back to its caller until the awaited task is complete. – Hem Bhagat Commented May 20, 2021 at 15:04
Add a comment  | 

2 Answers 2

Reset to default 17

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.

本文标签: AsyncAwait in Javascript vs CStack Overflow