coroutine,promise,async,awaitの私見

3589 ワード

結論:promise,async,awaitは不完全な抽象であり、coroutineは非同期開発に適しており、心の負担を解放している.
最近、nodejs、pythonの発展は、少し読めません.Nodejsはその非同期ioの純粋さのため、webサーバ上の超高性能で、大きな注目と発展を得た.その重要な特性は,非同期処理という点で,このように発展している.callbackはコールバック地獄の問題がありますpromiseコールバックツリーを平らに広げて、コードはもっとよくgeneratorを読んで本当に同期して非同期async,awaitを書いて同期して非同期のコードを書くことができます
pythonはGILの存在により,マルチスレッド処理に将来性はない.だからpythonのwebサーバは基本的にマルチプロセスの道を歩んでいます.マルチスレッドでもマルチプロセスでも、前の時代の処理方法であり、c10kを解決するのはpythonのwebサーバでの発展を整理するのに苦労しています.uWSGIサーバなどのマルチプロセス.性能は実際には十分なコールバックを使用することができます例えばtornadoはあまり詳しく理解していません.性能が高いことを知っています.コールバック地獄の問題があります.greenlet技術は何かよく使われるサーバーやwebフレームワークが出てくることを知りません.asyncio python 3.5 async,awaitも導入
まとめてみる
要するにioでは、2つのモデルしかありません.
  • 同期io
  • 非同期io
  • より高いパフォーマンスを実現するには、非同期ioのみが解決できます.次のような共通認識が得られます.
  • コールバックネストコールバック、本当に人が書くのに適していない、乱れている
  • promiseは平らになっただけで、少しよく見えますが、流れの流れは、異常との結合はよくありません.
  • async,awaitはpromiseの再包装にすぎず、本質は変わっていない.babelのasync,awaitに対するサポートはpromiseに変換することによって実現される
  • である.
    coroutine
    前にある説を見たことがありますが、
    coroutineはlispの継続特性のエッセンスを残しています
    coroutineとは
    coroutineは、ユーザによってスケジューリングされる呼び出しスタック、すなわち軽量スレッドである
    なぜcoroutineが非同期開発に適しているのか、
    例を挙げる
    これは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は同期マルチスレッドと同じ書き方ができることがわかります
    もう一つ例を挙げると、非同期とmapの結合
    これは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版では、ライブラリ関数を書く人は、ライブラリ関数が非同期であることに関心を持つ必要があります.呼び出し元も呼び出された関数が非同期であることに関心を持つ必要があります.awaitで待つ必要があります.awaitを呼び出した関数をasyncで修飾すると宣言します.coroutine版は、非同期のコードを同期的に書くことができます.同時にcoroutineはtry-catch異常処理と本当に自然に結合することができ、awaitはより多くの処理を行う必要がある.
    人月神話では、プログラムの主な複雑さは減らないが、人間の脳はすべての複雑さに細かく地面を残すことができないという話がある.したがって、プログラムアーキテクチャの本質は、オブジェクト向けの複雑さを管理し、遮蔽する3つの特徴であり、 のうち、最も有用なのは* 遮蔽複雑度* 正規化処理である.
    以上の認識に基づいて,coroutineは非同期による複雑さと知的負担を本当に遮断していることを知っており,これは実際の開発において大きな助けである.
    大火のgolangは、その競争者に比べて優位性が際立っており、そのgoroutine(特殊なcoroutine)に際立っている.
    推奨
  • openresty nginx、coroutine、webサーバ、ミドルウェア
  • skynet actor model、coroutine、ゲームサーバ