Node.js和.Net 4.5下的await、async相比有什麼不同?

如題,Node.js相比.Net 4.5加入的await、async非同步編程有什麼優點?

貌似.Net那個也是多並發,而且可以利用多核,配合c#代碼清晰明了,運行效率也比javascript高。為什麼很多項目習慣用Node.js?

另外,如果不考慮.Net,在Linux平台,Mono使用HttpClient 配合await async和v8引擎的Node.js,性能怎麼判定?


這個問題本身有問題,兩者嚴格說來沒有可比性。await/async是語言層面的東西,是編程模型。而你說的利用並發啊,多核啊,性能啊什麼的,那都是實現或者說執行方面的東西。JavaScript也在逐漸引入await,我正在等它引入了然後到處打臉去呢。


只能說,從編程模型上講,這倆是差不多的,一言以蔽之:同步非阻塞。

.NET里的async函數返回是一個Task&,JS里的async函數返回是一個Promise&,用起來感覺上是差不多的,當然Task還有cancel什麼的,我覺得是要比Promise更加強大的,不過並不是這個討論的重點,按住不表。

.NET里對async/await的實現,是基於System.Threading.Task類庫提供的一大堆Task相關的類。

JS里的async/await,目前(似乎)還沒有JS引擎有直接實現,所以並不知道它會實現成什麼樣。

我們知道JS是一個單線程的語言,ES2015中yield/generator給JS提供了新的可能性,諸如co這樣的用法將yield/generator包裝成了跟async/await非常近似的語法。

yield/generator在JS引擎里的實現,其實我也沒有研究過,並且我也沒有看過ES的Spec對這個實現有沒有要求,所以這裡不能下結論。

但是曾經有一個工具叫regenerator的,它可以把yield/generator轉譯成一堆看起來像是狀態機的代碼, @趙劼也早在2009(?)年就實現了Wind.js,將async/await代碼轉義成一堆難以閱讀的代碼。也就是說,yield/generator、async/await,它們也都不一定就是要runtime支持的,它可以被實現為純純的糖衣。

由於實現的方式不止一種,比如我猜想yield/generator在V8里會用棧幀實現,而regenerator看起來像是狀態機,我記得老趙說Wind.js用了Monad(還是說CPS變換來著?記不太清)。所以我個人也不建議在理解基於yield/generator、async/await所編寫的「同步編寫,非同步執行」代碼時,過早代入協程這一類的概念,更不贊同就說他們是JS里的協程。

在回到題主最後的問題,我覺得是沒辦法比,第一是因為他們僅僅是語法、編程模型上非常相似而已,背後實現大不一樣。第二也是因為在JS這邊,async/await尚未原生支持,目前babel和typescript都還只是把async/await轉譯成yield/generator外加一個類似於co的wrapper,這樣的背景下做橫比,好像意義不大吧。


開源界選語言的原因是很複雜的,你不要覺得這是一個技術問題,這多半不是。

C#的await和async是一個超級甜的語法糖,他編譯後就跟node.js那種屎一樣的callback嵌套callback沒完沒了的代碼差不多。 @趙劼 以前的一個叫做wind.js的項目就是給javascript加上這個糖的,結果Node.js不要,於是Node.js的用戶一直都很苦逼。


.net 的 Task 用的是 comonad 的那套介面,JS 的 Promise 走的是 monad 的介面

——儘管 Cont 本身既是 monad 也是 comonad

// A cont monad of X is the double dual of X
function Cont(kkX) { this.run = kkX }
// functor rules
Cont.prototype.map = function(f) {
return new Cont(kY =&> this.run(x =&> kY(f(x))))
}
// pure : x -&> Cont x
Cont.pure = function(x){
return new Cont(kX =&> kX(x))
}
// ap : Cont x ~&> Cont (x -&> y) -&> Cont y
Cont.prototype.ap = function(contXY) {
return new Cont(kY =&> contXY.run(fXY =&> this.run(x =&> kY(fXY(x)))))
}
// bind : Cont x ~&> (x -&> Cont y) -&> Cont y
Cont.prototype.bind = function(xContY){
return new Cont(kY =&> this.run(x =&> xContY(x).run(kY)))
}
// extract : Cont x ~&> x
Cont.prototype.extract = function(){
return this.run(x =&> x)
}
// extend : Cont x ~&> (Cont x -&> y) -&> Cont y
Cont.prototype.extend = function(contX2Y){
return new Cont(kY =&> kY(contX2Y(this)))
}

至於為啥 promise 能去嵌套……因為有結合律啊


nodejs的非同步是單線程的,相對來說比較好理解。

.net 的await、async 好像還牽扯到多線程什麼的,不太清楚,希望有高手能解釋解釋。

參考:http://stackoverflow.com/questions/21336976/node-js-vs-async-await-in-net


Asynchronous Programming with Async and Await (C# and Visual Basic)

看起來微軟的 Async / Await 在非同步 I/O 的基礎上,更把某些可能執行較久的 CPU 密集的服務包裝成了非同步執行的風格。

Node.js 完全針對 I/O 設計;重型的計算通常應該是通過 MQ 之類發到後端執行進程(組)上去的,所以,架構類似。

那麼剩下的不同就是:

  1. 微軟把東西整合起來了
  2. 微軟還加了語法糖

這裡不討論好或者不好,有人喜歡有人不喜歡。區別就在於,微軟因為是一手掌控從編譯器到平台到 OS 的公司,他們可以這樣做;開源社區 JS 是 JS 的 community 非同步 I/O 是非同步 I/O 的項目,所以要做什麼盡量還是在自己的框架內完成。

至於語法糖,用預編譯器的 IcedCoffeeScript IcedCoffeeScript 比用 eval 的東西怎麼也聽起來看起來靠譜點不是么。


推薦閱讀:

如何提升ASP.NET網站首次打開速度?
.NET 下的性能問題如何定位?
自學編程十年,依然沒有編寫出過什麼有用的東西,想知道下一步怎麼走?
如何使一個變數的名稱等於另一個變數的值?-.net?
.NET Core是否會取代.NET Framework?

TAG:JavaScript | NET | Nodejs | Mono |