Javascript文档说,“它使你的代码
看起来像同步的”,而不是说“它使你的代码同步化”。
在行为上,javascript和c#在async/await方面没有区别。
async关键字表示此方法中存在异步操作。
await关键字有助于将CPS(continuation passing style)编码转换为看起来像同步的代码。 CPS类似于在promise后使用then()或在C# Tasks中使用ContinueWith()。
在“await”之前的任何代码都在当前线程下同步运行。当执行到达“await”时,等待的操作会在一个新线程下开始(不一定是新线程,但假设是新线程),因此异步操作开始,并且当前线程被释放。当等待的操作结束时,执行返回到“await”关键字所在的位置,继续执行。
javascript和C#的内部工作方式不同。
Javascript是事件驱动的。 Javascript中有一个主事件循环和一个单线程。当等待的操作完成时,在幕后会引发一个事件,主单线程继续执行异步函数的执行位置。
在C#中,没有事件循环或单个线程。我们要么使用手动线程并在它们完成工作后显式等待和加入它们,要么使用类似于async/await的东西代表我们管理线程和继续管理。使用TPL,C#'s async/await内部使用回调将异步代码的连续性传递给另一个任务。
无论如何,“await”关键字将复杂的嵌套then() -js-或ContinueWith() - c#-链转换为一个简单美丽的代码,看起来像一个普通的-同步的-代码。
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);
}
这两段代码是等价的。但是,后者更加简单易读。
Javascript和C#中的线程管理有所不同。
正如所说,在Javascript中只有一个线程。如果它由于任何原因被阻塞,页面将被阻塞。这就是浏览器在20-30秒后显示“页面未响应”或“此页面中存在阻止页面的Javascript代码”消息的时候。
在HTML5中引入了Worker线程,可以实现真正的单独线程。然而,这是另一个话题。
你可能会问,如果Javascript中只有一个线程,异步操作怎么可能在另一个线程下运行呢?!
好问题。在Javascript中,尽管只有一个单一线程,但有些对象本身就使用独立的线程。定时器 - setInterval() 和 setTimeout() - XMLHttpObject() 和 fetch() 是其中的好例子。因此,在Javascript中我们确实可以有异步代码。
最后一个点是C#使用线程的方式。在C#中,async/await是使用名为TPL(Task Parallel Library)的库工作的。在TPL的核心有一个名为Task的类,类似于异步任务。
我们需要知道的真正要点是,一个Task等同于一个异步操作,但并不意味着一个Task显式地使用单独的线程。TPL中有一个任务调度程序来控制内部线程的使用。如果Task的工作很快,使用单独的线程会浪费资源,所以该任务将在当前线程下运行。
我们唯一需要知道的是,Task是异步代码的逻辑单元。事实上,Task是为了解放我们手动管理线程而引入的,这几乎是低级别的代码。
使用async/await,我们不再需要所有的样板代码,以提供异步代码。我们可以专注于我们的业务代码。
await
不会阻塞线程。在此期间,其他操作仍然可以在其他地方进行(例如setInterval
)。然而,在await
下面的代码行将在await
完成后执行。它不会使异步操作同步化,只是一些解决 Promise 回调地狱的神奇语法糖。 - Jeremy ThilleTask
和JavaScript的Promise
在思想上是相似的。它们在如何利用资源(线程)进行async/await操作方面存在一些差异(因为C#是多线程的,而JS是单线程的),以及其他差异,例如对操作的控制(例如延迟启动、停止等)。然而,从编码/工程角度来看,它们提供了相同的体验。 - Yeldar Kurmangaliyev