異步編程的最高境界,就是根本不用關心它是否是異步html
.NET的async/await方式最早達到了這個境界。編程
和async/await寫法相比,Java的什麼ExecutorService以及回調之類設計都是慚愧無比的。固然,習慣了也沒啥,反正那Java的lamda表達式用着也能夠接受。網絡
人不知道更好的東西的時候其實也就無所謂難受,更況且如今Java強勢,.NET就算有好東西也發不出太大的影響...異步
不過能夠想象,若是Java9支持了這個寫法,那麼那些RxJava什麼的和回調有關係的各類lib都會成爲二等公民(對於某數據流式處理仍是須要的)。async
其實那麼多牛人,怎麼會想不到這點呢,爲啥還不改呢?也許是不想承受抄襲的罵名,而是想改得直接超越.NET的,也許是專利限制,誰知道呢。異步編程
想來又不是要改JVM,只是改點編譯器罷,支持把await的後的代碼自動編程回調函數,再把系統的一些費時間的method給多封裝一個返回AsyncResult<SomeReturnType>之類的method,多大的事兒啊,改了吧。函數
那些getter/setter不支持的事兒就不和你計較了,反正還有個Lombk預編譯加上@Gettr/@Setter之類的就能夠了。可這個async/await否則,就不容易由第三方用相似的方法實現了。線程
順便普及一下async+await是如何優雅的,最天然的語法,天才的想法。思路大體是這樣:設計
string someFunction() { AsyncResult<真實返回值類型> asyncResult = someApi(...); asyncResult.onComplete( 真實結果 -> { ...對結果的處理... } ); return something; }
string someFunction() { 真實返回值類型> result = await someApi(...); ...對結果的處理... return something; }
至關於編譯器自動把await語句後面的知道函數末尾的全部語句都編譯成了一個臨時的Lamda表達式了。 3. 可是這樣一來,異步的特性會逐層傳染,當前所在的函數someFunction也就馬上返回了,那到底返回成什麼好呢,這就是async的登場了。日誌
async string someFunction() { 真實返回值類型> result = await someApi(...); ...對結果的處理... return something; }
這就是告訴編譯器,誰要是調用someFunction,他也必須用await罩一下。
string x = await someFunction() ...
就這麼想着想着改巴改巴就成了。
更具體的,就隨手轉帖一個有關.NET async/await的實現背後 « 司維的思惟。
async/await多美啊,實在符合天然思惟,看到await,就明白後面的代碼會等會兒再執行,暫時能夠回家吃飯去了。
可是,也有缺點,await只能取得一個結果,而後就不搞了。 這對於陸陸續續出若干個結果的API,就沒什麼做用,難道把一個流做爲返回值,那最終,仍是須要RxJava那種針對流處理的Publisher/Subscriber+Callback的方式。 這就是yield的登場了,它沒有async/await直觀好懂,就很少說了。
順便轉個 JavaScript async/await 函數的含義和用法 - 阮一峯的網絡日誌,裏面也有提到yield,看看就知道了。
真想不到之前弱弱的Java和JavaScript成長到如今這麼強大,真真是凝聚着無數高手們的心血,硬是擠得.NET直哆嗦(即便.NET在實現上依然優於Java,可是事兒不是那麼單純的)。真是白讓我之前那麼喜歡.NET。