다음을 통해 공유


Control.Observable 모듈(F#)

첫 번째 클래스 이벤트 및 관찰 가능한 다른 개체에 대한 기본 연산입니다.

네임스페이스/모듈 경로: Microsoft.FSharp.Control

어셈블리: FSharp.Core(FSharp.Core.dll)

module Observable

설명

추가 : ('T -> unit) -> IObservable<'T> -> unit

지정된 관찰 가능 개체를 영구적으로 구독하고 각 관찰에 대해 지정된 함수를 호출하는 관찰자를 만듭니다.

choose : ('T -> 'U option) -> IObservable<'T> -> IObservable<'U>

지정한 함수를 사용하여 소스에서 관찰 프로젝션을 선택하는 관찰 가능 개체를 반환합니다. 반환된 개체는 분할자가 Some 값을 반환하는 관찰을 트리거합니다. 또한 반환된 개체는 소스에서 발생하는 모든 오류를 전파하고 소스가 완료되면 완료됩니다.

filter : ('T -> bool) -> IObservable<'T> -> IObservable<'T>

지정된 함수로 소스의 관찰을 필터링하는 관찰 가능 개체를 반환합니다. 관찰 가능 개체는 조건자가 true를 반환하는 관찰만 확인합니다. 조건자는 구독된 각 관찰자에 대해 한 번씩만 실행됩니다. 또한 반환된 개체는 소스에서 발생하는 오류 관찰을 전파하고 소스가 완료되면 완료됩니다.

map : ('T -> 'U) -> IObservable<'T> -> IObservable<'U>

지정된 함수로 소스의 관찰을 변환하는 관찰 가능 개체를 반환합니다. 변환 함수는 구독된 각 관찰자에 대해 한 번씩만 실행됩니다. 또한 반환된 개체는 소스에서 발생하는 오류 관찰을 전파하고 소스가 완료되면 완료됩니다.

merge : IObservable<'T> -> IObservable<'T> -> IObservable<'T>

소스에서 병합된 관찰에 대한 관찰 가능 개체를 반환합니다. 반환된 개체는 두 소스에서 발생하는 성공 및 오류 값을 전파하고 두 소스가 모두 완료되면 완료됩니다.

pairwise : IObservable<'T> -> IObservable<'T * 'T>

입력 관찰 가능 개체의 두 번째 및 이후 트리거에서 트리거되는 새 관찰 가능 개체를 반환합니다. 입력 관찰 가능 개체의 N번째 트리거에서 N-1번째 및 N번째 트리거의 인수를 쌍으로 전달합니다. N-1번째로 트리거될 때 전달된 인수는 N번째 트리거가 발생할 때까지 숨겨진 내부 상태로 보관됩니다.

partition : ('T -> bool) -> IObservable<'T> -> IObservable<'T> * IObservable<'T>

지정된 함수로 소스의 관찰을 분할하는 두 개의 관찰 가능 개체를 반환합니다. 첫 번째는 조건자가 true를 반환하는 값에 대한 관찰을 트리거합니다. 두 번째 관찰 가능 개체는 조건자가 false를 반환하는 값에 대한 관찰을 트리거합니다. 조건자는 구독된 각 관찰자에 대해 한 번씩만 실행됩니다. 또한 두 관찰 가능 개체는 모두 소스에서 발생하는 모든 오류 관찰을 전파하고 소스가 완료되면 완료됩니다.

scan : ('U -> 'T -> 'U) -> 'U -> IObservable<'T> -> IObservable<'T>

각 관찰자에 대해 상태의 항목을 할당하고 입력에서 발생하는 연속 값에 지정된 누적 함수를 적용하는 관찰 가능 개체를 반환합니다. 반환된 개체는 초기 값을 제외하고 계산된 각 상태 값에 대한 관찰을 트리거합니다. 반환된 개체는 소스에서 발생하는 모든 오류를 전파하고 소스가 완료되면 완료됩니다.

split : ('T -> Choice<'U1,'U2>) -> IObservable<'T> -> IObservable<'U1> * IObservable<'U2>

지정된 함수로 소스의 관찰을 분할하는 두 개의 관찰 가능 개체를 반환합니다. 첫 번째는 분할자가 Choice1Of2를 반환하는 관찰을 트리거합니다. 두 번째 관찰 가능 개체는 분할자가 Choice2Of2를 반환하는 관찰 y를 트리거합니다. 분할자는 구독된 각 관찰자에 대해 한 번씩만 실행됩니다. 또한 두 관찰 가능 개체는 모두 소스에서 발생하는 오류 관찰을 전파하고 소스가 완료되면 완료됩니다.

subscribe : ('T -> unit) -> IObservable<'T> -> IDisposable

지정된 관찰 가능 개체를 구독하고 각 관찰에 대해 지정된 함수를 호출하는 관찰자를 만듭니다.

예제

다음 코드 예제에서는 관찰 가능한 항목을 사용하는 방법을 보여 줍니다. 이 예제에 정의된 ObserverSource 클래스는 눈에 띄는 이벤트의 원본으로 사용할 수 있는 재사용 가능한 범용 클래스입니다. 이 모듈에서 몇 가지 함수를 사용하는 예제를 여기에서 설명하며 이곳에서 보여주지 않는 함수의 경우 Control.Event 모듈(F#)의 코드 예제를 참조할 수 있습니다.

open System
open System.Diagnostics

// Represents a stream of IObserver events. 
type ObservableSource<'T>() =

    let protect function1 =
        let mutable ok = false 
        try 
            function1()
            ok <- true 
        finally
            Debug.Assert(ok, "IObserver method threw an exception.")

    let mutable key = 0

    // Use a Map, not a Dictionary, because callers might unsubscribe in the OnNext 
    // method, so thread-safe snapshots of subscribers to iterate over are needed. 
    let mutable subscriptions = Map.empty : Map<int, IObserver<'T>>

    let next(obs) = 
        subscriptions |> Seq.iter (fun (KeyValue(_, value)) -> 
            protect (fun () -> value.OnNext(obs)))

    let completed() = 
        subscriptions |> Seq.iter (fun (KeyValue(_, value)) -> 
            protect (fun () -> value.OnCompleted()))

    let error(err) = 
        subscriptions |> Seq.iter (fun (KeyValue(_, value)) -> 
            protect (fun () -> value.OnError(err)))

    let thisLock = new obj()

    let obs = 
        { new IObservable<'T> with 
            member this.Subscribe(obs) =
                let key1 =
                    lock thisLock (fun () ->
                        let key1 = key
                        key <- key + 1
                        subscriptions <- subscriptions.Add(key1, obs)
                        key1)
                { new IDisposable with  
                    member this.Dispose() = 
                        lock thisLock (fun () -> 
                            subscriptions <- subscriptions.Remove(key1)) } }

    let mutable finished = false 

    // The source ought to call these methods in serialized fashion (from 
    // any thread, but serialized and non-reentrant). 
    member this.Next(obs) =
        Debug.Assert(not finished, "IObserver is already finished")
        next obs

    member this.Completed() =
        Debug.Assert(not finished, "IObserver is already finished")
        finished <- true
        completed()

    member this.Error(err) =
        Debug.Assert(not finished, "IObserver is already finished")
        finished <- true
        error err

    // The IObservable object returned is thread-safe; you can subscribe  
    // and unsubscribe (Dispose) concurrently. 
    member this.AsObservable = obs

// Create a source. 
let source = new ObservableSource<int>()

// Get an IObservable from the source. 
let obs = source.AsObservable 

// Add a simple subscriber. 
let unsubA = obs |> Observable.subscribe (fun x -> printfn "A: %d" x)

// Send some messages from the source. 
// Output: A: 1
source.Next(1)
// Output: A: 2
source.Next(2)

// Add another subscriber. This subscriber has a filter. 
let unsubB =
    obs
    |> Observable.filter (fun num -> num % 2 = 0)
    |> Observable.subscribe (fun num -> printfn "B: %d" num)

// Send more messages from the source. 
// Output: A: 3
source.Next(3)
// Output: A: 4 
//         B: 4
source.Next(4)

// Have subscriber A unsubscribe.
unsubA.Dispose()

// Send more messages from the source. 
// No output
source.Next(5)
// Output: B: 6
source.Next(6)

// If you use add, there is no way to unsubscribe from the event.
obs |> Observable.add(fun x -> printfn "C: %d" x)

// Now add a subscriber that only does positive numbers and transforms 
// the numbers into another type, here a string. 
let unsubD =
    obs |> Observable.choose (fun int1 ->
             if int1 >= 0 then None else Some(int1.ToString()))
        |> Observable.subscribe(fun string1 -> printfn "D: %s" string1)

let unsubE =
    obs |> Observable.filter (fun int1 -> int1 >= 0)
        |> Observable.subscribe(fun int1 -> printfn "E: %d" int1)

let unsubF =
    obs |> Observable.map (fun int1 -> int1.ToString())
        |> Observable.subscribe (fun string1 -> printfn "F: %s" string1)

플랫폼

Windows Windows 서버 2012, Windows Server 2008 R2, Windows 7, 8

버전 정보

F# 코어 라이브러리 버전

지원: 2.0, 4.0, 노트북

참고 항목

참조

Microsoft.FSharp.Control 네임스페이스(F#)