すでに知っているはずですが、boost.asio を使用していることを考えると、boost.asio を使用すると、そこに到達することができます。しかし、それは同じになるつもりはありません。理由を説明しましょう。
node と asio はどちらもプロアクターのアイデアに基づいて設計されています。何かをブロックする (または単に遅い) 場合は、ジョブをプロアクターに送信します。ジョブは適切なときに実行され、終了時にコールバックを呼び出します。
しかし、ノードでは、すべてがプロクターを通過します。他の種類の非同期 API はありません。MySQL データベースと対話したい場合、インターフェースは SQL ステートメントを受け取り、行セットでコールバックします。C++ では、インターフェイスは SQL ステートメントを受け取り、カーソルを与える前にブロックするか、ポーリングまたはブロックできるオブジェクトを与えます。ファイルとソケットの場合、 asio には完全なラッパーがあるため、 select
orのような他のすべての API を無視できますがaio_read
、それ以外のほとんどの場合、ラッパーを作成する作業を行う必要があり、多くの場合、それは大変な作業になります。
もっと深刻なことに、ノードの標準コールバック インターフェイスは ですcallback(error, result)
。ここで、result
は適切な任意のメンバーを持つことができる JS オブジェクトです。asio の標準コールバック インターフェイスはvoid callback(const error_code&)
で、結果はありません。変更可能なオブジェクトをタスクにバインドします。前のオブジェクトが可変データをどのように隠蔽したかを知らずにオブジェクトが別のオブジェクトをフォローすることはできないため、これはすでに制御フローを行うのをより不器用にします。これは、必要かどうかに関係なく、共有された変更可能なデータ (ノードとは異なり、スレッド間で共有される可能性がある) が必要であることも意味します。しかし、もちろん最大の問題は、データが静的に型付けされていることです。(多くの場合、人々は C++ クラスを構築し、タスクを同じオブジェクトのバインドされたメソッドにすることで状態を共有しますが、実際には必要ありません。)
もちろん、C++ で完全に動的なオブジェクトを実行するコードを作成することはできます (または、a のように 1 レベルの動的性だけvector<boost::any>
で十分です)。 C++ に移行することで得られると期待していたパフォーマンス上の利点。
したがって、 とvoid async::waterfall(vector<void(const error_code&)>> tasks)
まったく同じことを行うような関数を作成するのは非常に簡単async.waterfall(tasks)
ですが、探しているのと同じ利点がすべて得られるわけではありません。
考慮すべきもう 1 つの点は、何らかの理由で C++ に切り替えたことです。速度が遅く、リソースに制約のあるシステムを使用しているからです。proactor を使用して と同等のデータ並列処理を実現することasync.forEach
は不可能ではありませんが、単純な古いスレッド プールとそれを使用する方法を知っている parallel-for ライブラリほど効率的ではありません。