Upgrade to Pro — share decks privately, control downloads, hide ads and more …

WHATWG Streams をためした - bouzuya / whatwg-streams-kyotojs-11

bouzuya
October 22, 2016

WHATWG Streams をためした - bouzuya / whatwg-streams-kyotojs-11

『WHATWG Streams をためした』
2016-10-22 Kyoto.js #11 bouzuya
http://kyotojs.connpass.com/event/39462/

Links:
- HTML version : http://bouzuya.net/slides/2016-10-22/
- bouzuya : http://bouzuya.net/
- github.com/bouzuya : https://github.com/bouzuya
- hatena.ne.jp/bouzuya : http://hatena.ne.jp/bouzuya
- twitter.com/bouzuya : https://twitter.com/bouzuya
- FaithCreates Inc. : http://www.faithcreates.co.jp/
- RALLY : https://rallyapp.jp/
- Streams Standard 日本語訳 : https://triple-underscore.github.io/Streams-ja.html
- https://speakerdeck.com/jxck/stream-between-nodejs-and-whatwg : https://speakerdeck.com/jxck/stream-between-nodejs-and-whatwg
- bouzuya/cycle-whatwg-streams-example : https://github.com/bouzuya/cycle-whatwg-streams-example
- bouzuya/whatwg-streams-b : https://github.com/bouzuya/whatwg-streams-b
- bouzuya/whatwg-streams-fns : https://github.com/bouzuya/whatwg-streams-fns

bouzuya

October 22, 2016
Tweet

More Decks by bouzuya

Other Decks in Programming

Transcript

  1. WHATWG Streams
    をためした
    2016-10-22 Kyoto.js #11 bouzuya
    1 / 43

    View Slide

  2. ぼく
    2 / 43

    View Slide

  3. bouzuya
    3 / 43

    View Slide

  4. github.com/bouzuya
    hatena.ne.jp/bouzuya
    twitter.com/bouzuya
    4 / 43

    View Slide

  5. FaithCreates Inc.
    神戸 (Kobe)
    Web + Android + iOS
    RALLY
    誰でも簡単にスタンプラリー
    をつくれるサー
    ビス
    Co eeScript + AngularJS
    Ruby + Ruby on Rails
    5 / 43

    View Slide

  6. WHATWG Streams
    6 / 43

    View Slide

  7. 調査:
    認知度は?
    7 / 43

    View Slide

  8. そもそも Stream
    って何?
    8 / 43

    View Slide

  9. 名前からすると流れるもの?
    9 / 43

    View Slide

  10. web
    プラットフォー
    ムの相当部分は、
    ストリー
    ミングデー
    タ上に築かれている:
    すな
    わち,
    デー
    タは、
    全部を記憶域内に読取ることなく,
    増分的なやり方で、
    作成され,

    理され,
    消費される。
    ――WHATWG Streams
    日本語訳
    10 / 43

    View Slide

  11. ぼくの中での Stream
    デー
    タ構造の一種
    デー
    タをひとつではなく連続したいくつかのものとして扱える
    デー
    タを一度ではなく連続した何度かで処理できる
    デー
    タを流せる・
    デー
    タが流れてくる
    具体例 (JS)
    Node.js Stream
    gulp
    RxJS Observable / ES.next Observable
    11 / 43

    View Slide

  12. WHATWG Streams
    策定の経緯
    12 / 43

    View Slide

  13. 知らない。
    興味ない。
    想像: WHATWG Fetch
    が一括ドンだからでは……
    13 / 43

    View Slide

  14. (5 min)
    14 / 43

    View Slide

  15. 3
    つの Stream
    クラス
    1. ReadableStream
    2. WritableStream
    3. TransformStream
    15 / 43

    View Slide

  16. 1. ReadableStream
    読み取りのための Stream
    Source
    から読んだデー
    タを内部キュー
    にためる
    c
    l
    a
    s
    s R
    e
    a
    d
    a
    b
    l
    e
    S
    t
    r
    e
    a
    m {
    c
    o
    n
    s
    t
    r
    u
    c
    t
    o
    r
    (
    u
    n
    d
    e
    r
    l
    y
    i
    n
    g
    S
    o
    u
    r
    c
    e
    : S
    o
    u
    r
    c
    e
    , o
    p
    t
    i
    o
    n
    s
    ?
    : R
    e
    a
    d
    a
    b
    l
    e
    S
    t
    r
    e
    a
    m
    O
    p
    t
    i
    o
    n
    s
    )
    ;
    g
    e
    t l
    o
    c
    k
    e
    d
    (
    )
    : b
    o
    o
    l
    e
    a
    n
    ;
    c
    a
    n
    c
    e
    l
    (
    r
    e
    a
    s
    o
    n
    : a
    n
    y
    )
    : P
    r
    o
    m
    i
    s
    e
    <
    v
    o
    i
    d
    >
    ;
    g
    e
    t
    R
    e
    a
    d
    e
    r
    (
    )
    : R
    e
    a
    d
    e
    r
    ;
    p
    i
    p
    e
    T
    h
    r
    o
    u
    g
    h
    (
    t
    r
    a
    n
    s
    f
    o
    r
    m
    : T
    r
    a
    n
    s
    f
    o
    r
    m
    S
    t
    r
    e
    a
    m
    , o
    p
    t
    i
    o
    n
    s
    ?
    : P
    i
    p
    e
    T
    o
    O
    p
    t
    i
    o
    n
    s
    )
    : R
    e
    a
    d
    a
    b
    l
    e
    S
    t
    r
    e
    a
    m
    ;
    p
    i
    p
    e
    T
    o
    (
    w
    r
    i
    t
    a
    b
    l
    e
    : W
    r
    i
    t
    a
    b
    l
    e
    S
    t
    r
    e
    a
    m
    , o
    p
    t
    i
    o
    n
    s
    ?
    : P
    i
    p
    e
    T
    o
    O
    p
    t
    i
    o
    n
    s
    )
    : P
    r
    o
    m
    i
    s
    e
    <
    v
    o
    i
    d
    >
    ;
    t
    e
    e
    (
    )
    : [
    R
    e
    a
    d
    a
    b
    l
    e
    S
    t
    r
    e
    a
    m
    , R
    e
    a
    d
    a
    b
    l
    e
    S
    t
    r
    e
    a
    m
    ]
    ;
    }
    16 / 43

    View Slide

  17. 2. WritableStream
    書き込みのための Stream
    Sink
    に書くデー
    タを内部キュー
    にためる
    c
    l
    a
    s
    s W
    r
    i
    t
    a
    b
    l
    e
    S
    t
    r
    e
    a
    m {
    c
    o
    n
    s
    t
    r
    u
    c
    t
    o
    r
    (
    u
    n
    d
    e
    r
    l
    y
    i
    n
    g
    S
    i
    n
    k
    : S
    i
    n
    k
    , o
    p
    t
    i
    o
    n
    s
    ?
    : W
    r
    i
    t
    a
    b
    l
    e
    S
    t
    r
    e
    a
    m
    O
    p
    t
    i
    o
    n
    s
    )
    ;
    g
    e
    t l
    o
    c
    k
    e
    d
    (
    )
    : b
    o
    o
    l
    e
    a
    n
    ;
    a
    b
    o
    r
    t
    (
    r
    e
    a
    s
    o
    n
    : a
    n
    y
    )
    : P
    r
    o
    m
    i
    s
    e
    <
    v
    o
    i
    d
    >
    ;
    g
    e
    t
    W
    r
    i
    t
    e
    r
    (
    )
    : W
    r
    i
    t
    e
    r
    ;
    }
    17 / 43

    View Slide

  18. 3. TransformStream
    変換のための Stream
    まだ仕様にない
    c
    l
    a
    s
    s T
    r
    a
    n
    s
    f
    o
    r
    m
    S
    t
    r
    e
    a
    m {
    c
    o
    n
    s
    t
    r
    u
    c
    t
    o
    r
    (
    t
    r
    a
    n
    s
    f
    o
    r
    m
    e
    r
    : T
    r
    a
    n
    s
    f
    o
    r
    m
    e
    r
    )
    ;
    g
    e
    t r
    e
    a
    d
    a
    b
    l
    e
    (
    )
    : R
    e
    a
    d
    a
    b
    l
    e
    S
    t
    r
    e
    a
    m
    ;
    g
    e
    t w
    r
    i
    t
    a
    b
    l
    e
    (
    )
    : W
    r
    i
    t
    a
    b
    l
    e
    S
    t
    r
    e
    a
    m
    ;
    }
    18 / 43

    View Slide

  19. Pipe chain (1)
    3
    種の Stream
    を pipe
    する (= pipe chain
    をつくる)
    RS -(pipe)-> WS
    RS -(pipe)-> TS -(pipe)-> ... -(pipe)-> WS
    RS -(pipe)-> WS + RS -(pipe)-> WS
    pipe chain
    を chunk
    が流れる
    chunk
    は RS / WS
    が読み書きするデー
    タの単位
    19 / 43

    View Slide

  20. c
    o
    n
    s
    t d
    a
    t
    a = [
    1
    , 2
    , 3
    ]
    ;
    n
    e
    w R
    e
    a
    d
    a
    b
    l
    e
    S
    t
    r
    e
    a
    m
    (
    {
    p
    u
    l
    l
    (
    c
    o
    n
    t
    r
    o
    l
    l
    e
    r
    ) {
    c
    o
    n
    s
    t c
    h
    u
    n
    k = d
    a
    t
    a
    .
    s
    h
    i
    f
    t
    (
    )
    ;
    c
    o
    n
    t
    r
    o
    l
    l
    e
    r
    .
    e
    n
    q
    u
    e
    u
    e
    (
    c
    h
    u
    n
    k
    )
    ; /
    / 1
    , 2
    , 3
    }
    }
    )
    .
    p
    i
    p
    e
    T
    h
    r
    o
    u
    g
    h
    (
    n
    e
    w T
    r
    a
    n
    s
    f
    o
    r
    m
    S
    t
    r
    e
    a
    m
    (
    {
    t
    r
    a
    n
    s
    f
    o
    r
    m
    (
    c
    h
    u
    n
    k
    , c
    o
    n
    t
    r
    o
    l
    l
    e
    r
    ) {
    c
    o
    n
    t
    r
    o
    l
    l
    e
    r
    .
    e
    n
    q
    u
    e
    u
    e
    (
    c
    h
    u
    n
    k * 2
    )
    ;
    }
    }
    )
    )
    .
    p
    i
    p
    e
    T
    o
    (
    n
    e
    w W
    r
    i
    t
    a
    b
    l
    e
    S
    t
    r
    e
    a
    m
    (
    {
    w
    r
    i
    t
    e
    (
    c
    h
    u
    n
    k
    ) {
    c
    o
    n
    s
    o
    l
    e
    .
    l
    o
    g
    (
    c
    h
    u
    n
    k
    )
    ; /
    / 2
    , 4
    , 6
    }
    }
    )
    )
    ;
    20 / 43

    View Slide

  21. Source
    と Sink
    1. Underlying Source
    2. Underlying Sink
    21 / 43

    View Slide

  22. 1. Source
    RS
    に wrap
    されるデー
    タの発生源
    Push / Pull
    の違いを吸収する
    Push Source
    例: TCP
    ソケット
    Pull Source
    例:
    ファイルハンドル
    Backpressure
    を考慮する (
    後述)
    i
    n
    t
    e
    r
    f
    a
    c
    e S
    o
    u
    r
    c
    e {
    t
    y
    p
    e
    ?
    : '
    b
    y
    t
    e
    s
    ' | u
    n
    d
    e
    f
    i
    n
    e
    d
    ;
    s
    t
    a
    r
    t
    ?
    (
    c
    o
    n
    t
    r
    o
    l
    l
    e
    r
    : R
    e
    a
    d
    a
    b
    l
    e
    S
    t
    r
    e
    a
    m
    C
    o
    n
    t
    r
    o
    l
    l
    e
    r
    )
    : P
    r
    o
    m
    i
    s
    e
    <
    v
    o
    i
    d
    > | u
    n
    d
    e
    f
    i
    n
    e
    d
    ;
    p
    u
    l
    l
    ?
    (
    c
    o
    n
    t
    r
    o
    l
    l
    e
    r
    : R
    e
    a
    d
    a
    b
    l
    e
    S
    t
    r
    e
    a
    m
    C
    o
    n
    t
    r
    o
    l
    l
    e
    r
    )
    : P
    r
    o
    m
    i
    s
    e
    <
    v
    o
    i
    d
    > | u
    n
    d
    e
    f
    i
    n
    e
    d
    ;
    c
    a
    n
    c
    e
    l
    ?
    (
    r
    e
    a
    s
    o
    n
    : a
    n
    y
    )
    : P
    r
    o
    m
    i
    s
    e
    <
    v
    o
    i
    d
    > | u
    n
    d
    e
    f
    i
    n
    e
    d
    ;
    }
    22 / 43

    View Slide

  23. 2. Sink
    WS
    に wrap
    されるデー
    タの行き先
    Backpressure
    を考慮する (
    後述)
    i
    n
    t
    e
    r
    f
    a
    c
    e S
    i
    n
    k {
    s
    t
    a
    r
    t
    ?
    (
    c
    o
    n
    t
    r
    o
    l
    l
    e
    r
    : W
    r
    i
    t
    a
    b
    l
    e
    S
    t
    r
    e
    a
    m
    C
    o
    n
    t
    r
    o
    l
    l
    e
    r
    )
    : P
    r
    o
    m
    i
    s
    e
    <
    v
    o
    i
    d
    > | u
    n
    d
    e
    f
    i
    n
    e
    d
    ;
    w
    r
    i
    t
    e
    ?
    (
    c
    h
    u
    n
    k
    : a
    n
    y
    )
    : P
    r
    o
    m
    i
    s
    e
    <
    v
    o
    i
    d
    > | u
    n
    d
    e
    f
    i
    n
    e
    d
    ;
    c
    l
    o
    s
    e
    ?
    (
    )
    : P
    r
    o
    m
    i
    s
    e
    <
    v
    o
    i
    d
    > | u
    n
    d
    e
    f
    i
    n
    e
    d
    ;
    a
    b
    o
    r
    t
    ?
    (
    r
    e
    a
    s
    o
    n
    : a
    n
    y
    )
    : P
    r
    o
    m
    i
    s
    e
    <
    v
    o
    i
    d
    > | u
    n
    d
    e
    f
    i
    n
    e
    d
    ;
    }
    23 / 43

    View Slide

  24. なぜ Source
    と Sink
    が重要か?
    使用時に RS / WS
    を継承しない
    constructor
    に Source / Sink
    を指定する
    n
    e
    w R
    e
    a
    d
    a
    b
    l
    e
    S
    t
    r
    e
    a
    m
    (
    s
    o
    u
    r
    c
    e
    , o
    p
    t
    i
    o
    n
    s
    )
    n
    e
    w W
    r
    i
    t
    a
    b
    l
    e
    S
    t
    r
    e
    a
    m
    (
    s
    i
    n
    k
    , o
    p
    t
    i
    o
    n
    s
    )
    Source / Sink
    はクラスとして提供されない
    Source / Sink
    のインタフェー
    スを実装する
    24 / 43

    View Slide

  25. c
    o
    n
    s
    t d
    a
    t
    a = [
    1
    , 2
    , 3
    ]
    ;
    n
    e
    w R
    e
    a
    d
    a
    b
    l
    e
    S
    t
    r
    e
    a
    m
    (
    { /
    / *
    *
    S
    o
    u
    r
    c
    e
    *
    *
    p
    u
    l
    l
    (
    c
    o
    n
    t
    r
    o
    l
    l
    e
    r
    ) {
    c
    o
    n
    s
    t c
    h
    u
    n
    k = d
    a
    t
    a
    .
    s
    h
    i
    f
    t
    (
    )
    ;
    c
    o
    n
    t
    r
    o
    l
    l
    e
    r
    .
    e
    n
    q
    u
    e
    u
    e
    (
    c
    h
    u
    n
    k
    )
    ; /
    / 1
    , 2
    , 3
    }
    }
    )
    .
    p
    i
    p
    e
    T
    h
    r
    o
    u
    g
    h
    (
    n
    e
    w T
    r
    a
    n
    s
    f
    o
    r
    m
    S
    t
    r
    e
    a
    m
    (
    {
    t
    r
    a
    n
    s
    f
    o
    r
    m
    (
    c
    h
    u
    n
    k
    , c
    o
    n
    t
    r
    o
    l
    l
    e
    r
    ) {
    c
    o
    n
    t
    r
    o
    l
    l
    e
    r
    .
    e
    n
    q
    u
    e
    u
    e
    (
    c
    h
    u
    n
    k * 2
    )
    ;
    }
    }
    )
    )
    .
    p
    i
    p
    e
    T
    o
    (
    n
    e
    w W
    r
    i
    t
    a
    b
    l
    e
    S
    t
    r
    e
    a
    m
    (
    { /
    / *
    *
    S
    i
    n
    k
    *
    *
    w
    r
    i
    t
    e
    (
    c
    h
    u
    n
    k
    ) {
    c
    o
    n
    s
    o
    l
    e
    .
    l
    o
    g
    (
    c
    h
    u
    n
    k
    )
    ; /
    / 2
    , 4
    , 6
    }
    }
    )
    )
    ;
    25 / 43

    View Slide

  26. Pipe chain (2)
    1. ( Underlying Source )
    2. ReadableStream
    3. [ TransformStream ]
    4. WritableStream
    5. ( Underlying Sink )
    26 / 43

    View Slide

  27. (10 min)
    27 / 43

    View Slide

  28. WHATWG Streams
    の特徴
    ロック
    バックプレッシャー
    28 / 43

    View Slide

  29. ロック
    29 / 43

    View Slide

  30. ReadableStream
    の読み取り操作
    p
    i
    p
    e
    T
    o
    (
    w
    r
    i
    t
    a
    b
    l
    e
    : W
    S
    )
    : P
    r
    o
    m
    i
    s
    e
    <
    v
    o
    i
    d
    >
    …… WS
    に pipe
    p
    i
    p
    e
    T
    h
    r
    o
    u
    g
    h
    (
    t
    r
    a
    n
    s
    f
    o
    r
    m
    : T
    S
    )
    : R
    S
    …… TS
    に pipe
    t
    e
    e
    (
    )
    : [
    R
    S
    , R
    S
    ]
    …… RS
    を分岐
    g
    e
    t
    R
    e
    a
    d
    e
    r
    (
    )
    : R
    e
    a
    d
    e
    r
    ……
    上 3
    つの内部でも呼ばれる低レベルな操作
    30 / 43

    View Slide

  31. ロックとは?
    制約:
    ひとつの RS
    は同時にひとつの Reader
    しか持てない
    g
    e
    t
    R
    e
    a
    d
    e
    r
    (
    )
    : R
    e
    a
    d
    e
    r
    は Reader
    を確保 (=
    ロック)
    する
    Reader
    が開放されるまで別の Reader
    を確保できない
    名前に反した破壊的な操作

    すべての読み取り操作は破壊的な操作
    g
    e
    t l
    o
    c
    k
    e
    d
    (
    )
    : b
    o
    o
    l
    e
    a
    n
    でロックの有無を確認できる
    Reader
    は RS
    の内部キュー
    を dequeue
    する
    WritableStream
    の g
    e
    t
    W
    r
    i
    t
    e
    r
    (
    )
    も同様
    Node.js Stream / RxJS Observable
    とは大きく違う
    比較は https://speakerdeck.com/jxck/stream-between-nodejs-and-whatwg
    31 / 43

    View Slide

  32. バックプレッシャー
    32 / 43

    View Slide

  33. バックプレッシャー
    とは?
    流量制御
    例:
    書き込み中なのにどんどん読み込まれると詰まる
    Promise
    で待たせる
    Source
    や Sink
    のメソッドの完了を伝える
    QueuingStrategy
    で待たせる
    queue size
    で Source
    の p
    u
    l
    l
    (
    )
    を待たせる
    33 / 43

    View Slide

  34. Promise
    で待たせる
    l
    e
    t i
    n
    d
    e
    x = 0
    ;
    n
    e
    w R
    e
    a
    d
    a
    b
    l
    e
    S
    t
    r
    e
    a
    m
    (
    {
    p
    u
    l
    l
    (
    c
    o
    n
    t
    r
    o
    l
    l
    e
    r
    ) {
    i
    n
    d
    e
    x +
    = 1
    ;
    c
    o
    n
    t
    r
    o
    l
    l
    e
    r
    .
    e
    n
    q
    u
    e
    u
    e
    (
    i
    n
    d
    e
    x
    )
    ;
    /
    / p
    u
    l
    l
    (
    )
    は P
    r
    o
    m
    i
    s
    e
    の解決を待って (
    5
    0
    + m
    s
    待って)
    呼ばれる
    r
    e
    t
    u
    r
    n n
    e
    w P
    r
    o
    m
    i
    s
    e
    (
    (
    o
    k
    ) =
    > s
    e
    t
    T
    i
    m
    e
    o
    u
    t
    (
    o
    k
    , 5
    0
    )
    )
    ;
    }
    }
    )
    .
    p
    i
    p
    e
    T
    o
    (
    n
    e
    w W
    r
    i
    t
    a
    b
    l
    e
    S
    t
    r
    e
    a
    m
    (
    {
    w
    r
    i
    t
    e
    (
    c
    h
    u
    n
    k
    ) {
    c
    o
    n
    s
    o
    l
    e
    .
    l
    o
    g
    (
    c
    h
    u
    n
    k
    )
    ;
    /
    / w
    r
    i
    t
    e
    (
    )
    は P
    r
    o
    m
    i
    s
    e
    の解決を待って (
    1
    0
    0
    + m
    s
    待って)
    呼ばれる
    r
    e
    t
    u
    r
    n n
    e
    w P
    r
    o
    m
    i
    s
    e
    (
    (
    o
    k
    ) =
    > s
    e
    t
    T
    i
    m
    e
    o
    u
    t
    (
    o
    k
    , 1
    0
    0
    )
    )
    ;
    }
    }
    )
    )
    ;
    34 / 43

    View Slide

  35. QueuingStrategy
    で待たせる
    RS / WS
    の内部キュー
    をどうためるかの戦略
    上限を超えると Source
    の p
    u
    l
    l
    (
    )
    が呼ばれなくなる
    ※ Source
    は無視して enqueue
    し続けることもできる。
    c
    l
    a
    s
    s C
    o
    u
    n
    t
    Q
    u
    e
    u
    i
    n
    g
    S
    t
    r
    a
    t
    e
    g
    y {
    c
    o
    n
    s
    t
    r
    u
    c
    t
    o
    r
    (
    o
    p
    t
    i
    o
    n
    s
    : { h
    i
    g
    h
    W
    a
    t
    e
    r
    M
    a
    r
    k
    : n
    u
    m
    b
    e
    r
    ; }
    )
    ;
    g
    e
    t h
    i
    g
    h
    W
    a
    t
    e
    r
    M
    a
    r
    k
    (
    )
    : n
    u
    m
    b
    e
    r
    ; /
    / q
    u
    e
    u
    e s
    i
    z
    e
    の限界。
    s
    i
    z
    e
    (
    _
    c
    h
    u
    n
    k
    : a
    n
    y
    )
    : n
    u
    m
    b
    e
    r
    ; /
    / c
    h
    u
    n
    k s
    i
    z
    e
    の計算。
    このクラスでは常に 1 。
    }
    c
    l
    a
    s
    s B
    y
    t
    e
    L
    e
    n
    g
    t
    h
    Q
    u
    e
    u
    i
    n
    g
    S
    t
    r
    a
    t
    e
    g
    y {
    c
    o
    n
    s
    t
    r
    u
    c
    t
    o
    r
    (
    o
    p
    t
    i
    o
    n
    s
    : { h
    i
    g
    h
    W
    a
    t
    e
    r
    M
    a
    r
    k
    : n
    u
    m
    b
    e
    r
    ; }
    )
    ;
    g
    e
    t h
    i
    g
    h
    W
    a
    t
    e
    r
    M
    a
    r
    k
    (
    )
    : n
    u
    m
    b
    e
    r
    ;
    s
    i
    z
    e
    (
    c
    h
    u
    n
    k
    : { b
    y
    t
    e
    L
    e
    n
    g
    t
    h
    : n
    u
    m
    b
    e
    r
    ; }
    )
    : n
    u
    m
    b
    e
    r
    ;
    }
    35 / 43

    View Slide

  36. /
    / S
    o
    u
    r
    c
    e
    が q
    u
    e
    u
    e
    の s
    i
    z
    e
    を気にしながら e
    n
    q
    u
    e
    u
    e
    する例
    n
    e
    w R
    e
    a
    d
    a
    b
    l
    e
    S
    t
    r
    e
    a
    m
    (
    {
    s
    t
    a
    r
    t
    (
    c
    o
    n
    t
    r
    o
    l
    l
    e
    r
    ) {
    s
    e
    t
    T
    i
    m
    e
    o
    u
    t
    (
    (
    ) =
    > {
    l
    e
    t i
    n
    d
    e
    x = 0
    ;
    w
    h
    i
    l
    e (
    c
    o
    n
    t
    r
    o
    l
    l
    e
    r
    .
    d
    e
    s
    i
    r
    e
    d
    S
    i
    z
    e > 0
    ) { /
    / q
    u
    e
    u
    e
    に余裕がある限り e
    n
    q
    u
    e
    u
    e
    c
    o
    n
    t
    r
    o
    l
    l
    e
    r
    .
    e
    n
    q
    u
    e
    u
    e
    (
    i
    n
    d
    e
    x
    +
    +
    )
    ;
    }
    c
    o
    n
    t
    r
    o
    l
    l
    e
    r
    .
    c
    l
    o
    s
    e
    (
    )
    ;
    }
    )
    ;
    }
    }
    , n
    e
    w C
    o
    u
    n
    t
    Q
    u
    e
    u
    i
    n
    g
    S
    t
    r
    a
    t
    e
    g
    y
    (
    { h
    i
    g
    h
    W
    a
    t
    e
    r
    M
    a
    r
    k
    : 1
    0 }
    )
    ) /
    / q
    u
    e
    u
    e
    は 1
    0
    個まで
    .
    p
    i
    p
    e
    T
    o
    (
    n
    e
    w W
    r
    i
    t
    a
    b
    l
    e
    S
    t
    r
    e
    a
    m
    (
    .
    .
    .
    )
    )
    ;
    36 / 43

    View Slide

  37. (15 min)
    37 / 43

    View Slide

  38. ためしてみた
    38 / 43

    View Slide

  39. で、
    何に使う?
    あくまで Stream
    はデー
    タ構造
    何に使うかは自由
    ぼくは
    View + ViewModel / Model
    間の data ow
    に使ってみたい
    Flux + React
    からの unidirectional data ow
    なアレ
    時間もないので↓
    を実装した
    Cycle.js
    の adapter / run
    と TodoMVC (
    一部)
    39 / 43

    View Slide

  40. 結果
    bouzuya/cycle-whatwg-streams-example
    40 / 43

    View Slide

  41. わかったこと
    まず実装が NPM
    にない
    つくった→bouzuya/whatwg-streams-b
    そして helper (RxJS
    でいう operator)
    がない
    map / lter / reduce (scan) / merge
    など、
    なにもない
    つくった→ bouzuya/whatwg-streams-fns
    意外と快適 なんとかなる
    Model
    は RxJS
    と比べれば simple ……
    な気がする
    コアな操作って少ない (=
    いろいろ足りない)
    pipeThrough
    の構造が好き
    効率悪そう
    bind operator
    がほしくなりにくい
    TypeScript
    の型推論だと……
    41 / 43

    View Slide

  42. おまけ
    /
    / p
    i
    p
    e
    T
    h
    r
    o
    u
    g
    h
    の実装
    p
    i
    p
    e
    T
    h
    r
    o
    u
    g
    h
    (
    { r
    e
    a
    d
    a
    b
    l
    e
    , w
    r
    i
    t
    a
    b
    l
    e }
    , o
    p
    t
    i
    o
    n
    s
    ) {
    t
    h
    i
    s
    .
    p
    i
    p
    e
    T
    o
    (
    w
    r
    i
    t
    a
    b
    l
    e
    , o
    p
    t
    i
    o
    n
    s
    )
    ;
    r
    e
    t
    u
    r
    n r
    e
    a
    d
    a
    b
    l
    e
    ;
    }
    /
    / b
    o
    u
    z
    u
    y
    a
    /
    w
    h
    a
    t
    w
    g
    -
    s
    t
    r
    e
    a
    m
    s
    -
    f
    n
    s
    の例
    i
    m
    p
    o
    r
    t { f
    r
    o
    m } f
    r
    o
    m '
    w
    h
    a
    t
    w
    g
    -
    s
    t
    r
    e
    a
    m
    s
    -
    f
    n
    s
    /
    f
    r
    o
    m
    '
    ;
    i
    m
    p
    o
    r
    t { m
    a
    p } f
    r
    o
    m '
    w
    h
    a
    t
    w
    g
    -
    s
    t
    r
    e
    a
    m
    s
    -
    f
    n
    s
    /
    m
    a
    p
    '
    ;
    i
    m
    p
    o
    r
    t { f
    i
    l
    t
    e
    r } f
    r
    o
    m '
    w
    h
    a
    t
    w
    g
    -
    s
    t
    r
    e
    a
    m
    s
    -
    f
    n
    s
    /
    f
    i
    l
    t
    e
    r
    '
    ;
    f
    r
    o
    m
    (
    [
    1
    , 2
    , 3
    , 4
    , 5
    ]
    )
    .
    p
    i
    p
    e
    T
    h
    r
    o
    u
    g
    h
    (
    m
    a
    p
    (
    (
    i
    : n
    u
    m
    b
    e
    r
    ) =
    > i * 2
    )
    )
    .
    p
    i
    p
    e
    T
    h
    r
    o
    u
    g
    h
    (
    f
    i
    l
    t
    e
    r
    (
    (
    i
    : n
    u
    m
    b
    e
    r
    ) =
    > i =
    =
    = 3
    )
    )
    .
    p
    i
    p
    e
    T
    o
    (
    n
    e
    w W
    r
    i
    t
    a
    b
    l
    e
    S
    t
    r
    e
    a
    m
    (
    { w
    r
    i
    t
    e
    (
    c
    ) { c
    o
    n
    s
    o
    l
    e
    .
    l
    o
    g
    (
    c
    )
    ; } }
    )
    )
    ;
    42 / 43

    View Slide

  43. おしまい
    43 / 43

    View Slide