剖析

  1. 使用 Deno.listen 监听 Socket 端口,Deno Core 使用 Rust 实现了 socket 这一套的编程;
  2. 使用 Server 类中实现 AsyncIterableIterator 来实现 ServerRequest 的消费;
  1. class Server implements AsyncIterable<ServerRequest> {
  2. [Symbol.asyncIterator](): AsyncIterableIterator<ServerRequest> {
  3. const mux: MuxAsyncIterator<ServerRequest> = new MuxAsyncIterator();
  4. mux.add(this.acceptConnAndIterateHttpRequests(mux));
  5. return mux.iterate();
  6. }
  7. }
  1. MuxAsyncIterator The MuxAsyncIterator class multiplexes multiple async iterators into a

    single stream.
    首先得理清楚基础概念:

  • Generator
  • Iterator
  • Iterable
  • AsyncGenerator
  • AsyncIterable
  • AsyncIterator
  • AsyncIterableIterator ```typescript interface AsyncIterator { // NOTE: ‘next’ is defined using a tuple to ensure we report the correct assignability errors in all places. next(…args: [] | [TNext]): Promise>; return?( value?: TReturn | PromiseLike ): Promise>; throw?(e?: any): Promise>; }

interface AsyncGenerator extends AsyncIterator { // NOTE: ‘next’ is defined using a tuple to ensure we report the correct assignability errors in all places. next(…args: [] | [TNext]): Promise>; return(value: TReturn | PromiseLike): Promise>; throw(e: any): Promise>; Symbol.asyncIterator: AsyncGenerator; }

interface AsyncIterable { Symbol.asyncIterator: AsyncIterator; }

interface AsyncIterableIterator extends AsyncIterator { Symbol.asyncIterator: AsyncIterableIterator; }

然后尝试根据源代码,手动化简实现一个简单的 _MuxServer _来实现多 TCP 链接上 HTTPRequest 的多路复用,将多个流合并到一个处理模式下。

```typescript
class MuxServer implements AsyncIterable<string> {
  private tcpConnectionPool: TCPConnection = new TCPConnection();
  private async *iterateHttpRequests(conn: TCPConnection): AsyncIterableIterator<string> {
    while(true) {
      const msg = await conn.readHttpRequest();
      yield msg;
    }
  }

  private async *acceptConnAndIterateHttpRequests(mux: MuxAsyncIterator<string>): AsyncIterableIterator<string> {
    const connectionMsg = await this.tcpConnectionPool.listen();
    yield connectionMsg;
    mux.add(this.acceptConnAndIterateHttpRequests(mux));
    yield* this.iterateHttpRequests(this.tcpConnectionPool);
  }

  [Symbol.asyncIterator](): AsyncIterableIterator<string> {
    const mux: MuxAsyncIterator<string> = new MuxAsyncIterator();
    mux.add(this.acceptConnAndIterateHttpRequests(mux));
    return mux.iterate();
  }
}

📦 Github 源代码自取
🖋 Repl.it 上自行玩耍

这里是 Deno http 实现模块的精粹,但核心的网络编程还是交由 Rust 底层去实现的,这里就不作细节介绍了。

感受

人们总会不断尝试用新的事物去解决新的问题,AsyncIterable 的确让使用者以近乎同步的 code 写法实现异步事件和数据的消费,这的确是个比较好的编程写法,值得借鉴和学习。

在研究 MuxPlexer 多异步流合一的实现的时候,deno 的确给了一个比较好的实现范本,让我看到了 Rx.js 的影子。

Ref

这里是分享的 PPT:

AsyncIterableIterator in deno.pdf