using

자원을 한 번의 반복에 묶습니다. 첫 pull에 획득하고, 완료 시 에러 시든 정확히 한 번 해제합니다.

Iterable<T> using<R, T>(R Function() acquire, Iterable<T> Function(R resource) use, void Function(R resource) release) FxAsyncIterable<T> usingAsync<R, T>(FutureOr<R> Function() acquire, FxAsyncIterable<T> Function(R resource) use, FutureOr<void> Function(R resource) release)

강의

파일, 소켓, 데이터베이스 커서 — 이들이 만들어 내는 값은 시퀀스지만, 그 수명은 하나의 괄호(bracket)입니다. 열고, 읽고, 닫기 — 읽다가 예외가 던져져도 말입니다. 지연 파이프라인 둘레에 그 괄호를 쓰기는 어색한데, "반복이 끝나는 시점"이 소비자가 어디에 있느냐에 달려 있기 때문입니다. using(acquire, use, release)는 그 괄호를 반복 자체에 묶습니다. acquire는 첫 pull에 실행되고(파이프라인을 만드는 시점이 아닙니다 — 지연 평가가 보존됩니다), use(resource)가 원소들을 공급하며, release(resource)는 마지막 원소 뒤 또는 에러가 전파되기 직전에 정확히 한 번 실행됩니다.

비동기 형태인 usingAsync는 세 단계 모두 비동기일 수 있게 하며 concurrent와 조합됩니다 — 겹쳐 진행 중인 pull이 있어도 해제는 여전히 정확히 한 번만 일어납니다. acquire 자체가 실패하면 해제할 것이 없으므로 에러는 그냥 전파됩니다.

pull 모델에서 곧장 나오는 솔직한 주의 사항 하나. 반복을 중도 포기하는 소비자 — for-in 안의 break, 이터레이터를 그냥 버리는 것 — 는 끝에 도달하지 않으므로 release가 실행될 수 없습니다. take로 반복에 한도를 두거나 (한도가 있는 파이프라인은 완료되고, 완료는 해제로 이어집니다), 조기 종료가 계획이라면 try/finally로 자원을 직접 관리하세요. Dart 고유의 추가 기능입니다(FxTS에는 대응물이 없습니다). Rx의 using을 따랐습니다.

데모 1 · 지연 읽기 둘레의 괄호

데모 2 · 에러 시 해제, 정확히 한 번

직접 해 보기

연습: 연결(connection)에 수명을 부여해 보세요.

관련 항목: take — 반복에 한도를 두어 완료(그리고 해제)를 보장하기 · peek — 수명을 소유하지 않고 값 관찰하기 · retry — 팩터리로 감싸면 시도마다 새로 획득