share & LiveValue.from

체인 한 번의 실행, 여러 리스너 — 그리고 늦게 온 사람을 위해 최신 값을 기억하는 버전.

FxEvents<T> FxEvents<T>.share({bool reset = true}) // chain (events); resubscribes after last-cancel unless complete LiveValue<T>.from(Stream<T> source) // hot, unseeded LiveValue<T>.seededFrom(T seed, Stream<T> source) // hot, seeded

강의

이 섹션의 모든 연산자는 자기만의 StreamController를 만들므로, 돌려주는 체인은 단일 구독입니다: 두 번 리슨하면 두 번째 리스너는 StateError를 받습니다. 그 기본값은 의도적입니다 — 체인을 차갑게 유지해 누군가 소비하기 전까지 아무것도 실행되지 않게 하고, 리스너별 상태를 정직하게 지킵니다. 하지만 그것은 위젯 둘이 같은 debounce·throttle·switchMap 피드를 두 번 만들지 않고는 함께 볼 수 없다는 뜻이기도 합니다.

share()가 그것을 해결합니다. 리스너에서 연결하고 그때부터 모든 리스너에게 방송하므로, 몇 명이 보고 있든 상류의 일은 한 번만 일어납니다. debounce 타이머, 소켓, 비싼 map — 구독자마다 하나가 아니라 전부 하나씩입니다.

share({reset: true}) — 기본값 — 은 이제 Rx의 ref-count 리셋과 같습니다. 마지막 리스너가 소스가 완료되기 전에 떠나면, 상류 구독은 취소되고 다음 리스너는 새 구독을 시작합니다. 소스가 완료된 뒤에는, 나중에 오는 리스너는 여전히 닫힌 스트림을 받습니다. share(reset: false)는 0.8.7의 동작입니다: 마지막 취소가 영영 닫습니다. 재구독에는 두 번째 리슨을 허용하는 소스가 필요합니다 — Stream.fromIterable, Stream.multi, FxEvents.defer, 브로드캐스트 — 이미 소진된 단일 구독 StreamController는 여전히 다시 들을 수 없습니다. 소스가 한 번뿐이면 첫 이벤트 전에 모든 리스너를 붙이거나, 하나를 살려 두세요.

share()기억하지도 않습니다: 이벤트가 지나간 뒤에 도착한 리스너는 그냥 놓친 것입니다. 이력의 창이 필요하면 shareReplay가 다음 쪽입니다. 늦게 온 쪽이 현재 상태를 알아야 할 때 — 대부분의 UI가 그렇습니다 — LiveValue가 답이고, LiveValue.from(source)LiveValue.seededFrom(seed, source)이 스트림에서 바로 하나를 만듭니다. 이들은 뜨겁습니다: 구독이 즉시 열리므로 아무도 리슨하기 전에 도착한 값도 value를 갱신하고, close()는 소스를 취소합니다. 선택적 시드가 아니라 이름 붙은 생성자인 것은 널 가능한 T도 null로 시드할 수 있게 하기 위해서입니다. fxdart 이벤트 레이어, Rx의 shareshareValue를 따랐습니다.

데모 1 · 왜 리스너 하나가 기본값인가

데모 2 · 한 번의 실행, 두 리스너

직접 해 보기

연습: 스트림에서 바로 만든 LiveValue.

관련 항목: shareReplay — 이력 버퍼를 기억하는 멀티캐스트 · LiveValue — 기억하는 공유: 늦은 구독자가 현재 값을 먼저 받음 · tee — 한 번의 순회에 독자 둘, 버퍼 없이 — 풀 쪽의 답 · fork — 한 소스에 독립적인 풀 커서 둘, 버퍼를 대가로