coroutine, promise, async, await之我見(jiàn)

結(jié)論:promise, async, await 是不完全的抽象,coroutine更適合異步開(kāi)發(fā),解放心智負(fù)擔(dān)。

近來(lái),nodejs, python的發(fā)展,有些看不大懂。
nodejs由于其異步io的純粹,在web服務(wù)器上的超高性能,獲得了極大的關(guān)注和發(fā)展。
其關(guān)鍵特性,異步處理這塊上,是這樣發(fā)展的

callback 有回調(diào)地獄的問(wèn)題
promise 把回調(diào)樹(shù)平展開(kāi)來(lái),代碼更好閱讀
generator 真以同步寫(xiě)異步
async,await 以同步的方式來(lái)書(shū)寫(xiě)異步的代碼

python由于GIL的存在,在多線程處理上是沒(méi)有未來(lái)的。
所以python的web服務(wù)器基本上走的都是多進(jìn)程的路子。
多線程也好,多進(jìn)程也好,都是上個(gè)時(shí)代的處理方式,解決c10k都?jí)騿?br> 梳理下python在web服務(wù)器上的發(fā)展:

多進(jìn)程 例如 uWSGI 服務(wù)器。 性能其實(shí)也夠用了
回調(diào) 例如tornado 沒(méi)有很詳細(xì)的了解, 知道性能很高,有回調(diào)地獄的問(wèn)題
greenlet 技術(shù) 不了解有什么常用的服務(wù)器或者web框架出來(lái)
asyncio
python3.5也引入了async,await

總結(jié)一下

總之,io上,只有兩種模型:

  1. 同步io
  2. 異步io

想擁有更高的性能,只有異步io可以解決。然后如下幾個(gè)共識(shí):

  1. 回調(diào)嵌套回調(diào),真心不適合人寫(xiě)的,太亂
  2. promise只是展平了,看起來(lái)好點(diǎn)了,但是流程的流轉(zhuǎn),與異常的結(jié)合還是不好
  3. async, await只是promise的再包裝,本質(zhì)沒(méi)變。babel對(duì)async,await的支持就是通過(guò)轉(zhuǎn)化成promise來(lái)實(shí)現(xiàn)的

coroutine

之前看過(guò)一種說(shuō)法,

coroutine保留了lisp的續(xù)延特性的精華

什么是coroutine

coroutine 是由用戶調(diào)度的調(diào)用棧,即輕量線程

為什么說(shuō)coroutine更適合異步開(kāi)發(fā),

舉個(gè)例子

這是await版

async function selectPizza() {
  const pizzaData = await getPizzaData()    // async call
  const chosenPizza = choosePizza()    // sync call
  await addPizzaToCart(chosenPizza)    // async call
}

async function selectDrink() {
  const drinkData = await getDrinkData()    // async call
  const chosenDrink = chooseDrink()    // sync call
  await addDrinkToCart(chosenDrink)    // async call
}

(async () => {
  const pizzaPromise = selectPizza()
  const drinkPromise = selectDrink()
  await pizzaPromise
  await drinkPromise
  orderItems()    // async call
})()

這是lua的coroutine版

function selectPizza() 
  local pizzaData = getPizzaData()    // async call
  local chosenPizza = choosePizza()    // sync call
  addPizzaToCart(chosenPizza)    // async call
end

 function selectDrink() 
  local drinkData = getDrinkData()    // async call
  local chosenDrink = chooseDrink()    // sync call
 addDrinkToCart(chosenDrink)    // async call
end

(function ()
  selectPizza()
  selectDrink()
  orderItems()    // async call
end)()

可以看到,coroutine可以做到跟同步多線程一樣的寫(xiě)法

再舉個(gè)例子, 異步與map的結(jié)合

這是await版

var arr = [1, 2, 3, 4, 5];

var results = await Promise.all(arr.map(async (item)  => {
    await callAsynchronousOperation(item);
    return item + 1;
}));

這是lua的coroutine版

local arr = {1,2,3,4,5}
local results = arr.map(function (item) 
    callAsynchronousOperation(item)
    return item + 1
end)

兩者功能并不完全一樣

await版,寫(xiě)庫(kù)函數(shù)的人,需要關(guān)心庫(kù)函數(shù)是異步的,調(diào)用方也需要關(guān)心
所調(diào)用的函數(shù)是異步的,要用await去等待,并且聲明調(diào)用了await的函數(shù)要用async修飾。
coroutine版可以做到真正的以同步的方式來(lái)寫(xiě)異步的代碼。
同時(shí),coroutine可以真正自然地與try-catch異常處理結(jié)合,而await需要做更多的處理

在人月神話中,就有提到,程序的主要復(fù)雜度是不可減的,
人腦是無(wú)法巨細(xì)無(wú)遺地面對(duì)所有復(fù)雜度的。 所以程序架構(gòu)的本質(zhì)是管理并屏蔽復(fù)雜度
面向?qū)ο蟮娜筇卣鳎?code>封裝、繼承多態(tài)中,最有用的是
* 封裝 屏蔽復(fù)雜度
* 多態(tài) 歸一化處理

基于以上的認(rèn)識(shí),我們知道,coroutine真正的屏蔽了異步帶來(lái)的復(fù)雜度和心智負(fù)擔(dān),這在實(shí)際開(kāi)發(fā)中,幫助是巨大的。

大火的golang,相較于它的競(jìng)爭(zhēng)者,優(yōu)勢(shì)突出,突出在于它的goroutine(特殊的coroutine)

推薦

  • openresty nginx、coroutine、 web服務(wù)器,中間件
  • skynet actor model、coroutine、 游戲服務(wù)器
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 異步編程對(duì)JavaScript語(yǔ)言太重要。Javascript語(yǔ)言的執(zhí)行環(huán)境是“單線程”的,如果沒(méi)有異步編程,根本...
    呼呼哥閱讀 7,405評(píng)論 5 22
  • 一.非阻塞和異步 借用知乎用戶嚴(yán)肅的回答在此總結(jié)下,同步和異步是針對(duì)消息通信機(jī)制,同步代表一個(gè)client發(fā)出一個(gè)...
    Daniel_adu閱讀 1,925評(píng)論 0 8
  • 1、通過(guò)CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫(kù)組件 SD...
    陽(yáng)明AI閱讀 16,204評(píng)論 3 119
  • 簡(jiǎn)單介紹下這幾個(gè)的關(guān)系為方便起見(jiàn) 用以下代碼為例簡(jiǎn)單介紹下這幾個(gè)東西的關(guān)系, async 在函數(shù)聲明前使用asyn...
    _我和你一樣閱讀 21,486評(píng)論 1 24
  • 1 什么是異步編程 1.1 阻塞 程序未得到所需計(jì)算資源時(shí)被掛起的狀態(tài)。 程序在等待某個(gè)操作完成期間,自身無(wú)法繼續(xù)...
    dtdh閱讀 7,843評(píng)論 0 42

友情鏈接更多精彩內(nèi)容