Control.Observable (Módulo de F#)
Operaciones básicas con objetos de evento de primera clase y otros objetos observables.
Espacio de nombres/Ruta de acceso del módulo: Microsoft.FSharp.Control
Ensamblado: FSharp.Core (en FSharp.Core.dll)
module Observable
Valores
Valor |
Descripción |
---|---|
agregar : ('T -> unit) -> IObservable<'T> -> unit |
Crea un observador que se suscribe permanentemente al objeto observable especificado y llama a la función indicada para cada observación. |
choose : ('T -> 'U option) -> IObservable<'T> -> IObservable<'U> |
Devuelve un objeto observable que elige una proyección de observaciones del origen mediante la función especificada. El objeto devuelto desencadenará las observaciones para las que el divisor devuelve un valor Some. El objeto devuelto también propagará todos los errores procedentes del origen y se completará cuando se complete el origen. |
filter : ('T -> bool) -> IObservable<'T> -> IObservable<'T> |
Devuelve un objeto observable que filtra las observaciones del origen por la función especificada. El objeto observable verá solo las observaciones para las que el predicado devuelva true. El predicado se ejecuta una vez para cada observador suscrito. El objeto devuelto también propaga las observaciones de error procedentes del origen y se completa a la vez que el origen. |
map : ('T -> 'U) -> IObservable<'T> -> IObservable<'U> |
Devuelve un objeto observable que transforma las observaciones del origen por la función especificada. La función de transformación se ejecuta una vez para cada observador suscrito. El objeto devuelto también propaga las observaciones de error procedentes del origen y se completa a la vez que el origen. |
combinar : IObservable<'T> -> IObservable<'T> -> IObservable<'T> |
Devuelve un objeto observable para las observaciones combinadas de los orígenes. El objeto devuelto propaga los valores correctos y de error procedentes de los orígenes y se completa una vez completados ambos orígenes. |
pairwise : IObservable<'T> -> IObservable<'T * 'T> |
Devuelve un nuevo objeto observable que se desencadena la segunda vez y las veces subsiguientes que se desencadena el objeto observable de entrada. El enésimo desencadenamiento del objeto observable de entrada pasa los argumentos del enésimo encadenamiento y del enésimo desencadenamiento -1 como un par. El argumento que se pasa al enésimo desencadenamiento -1 se mantiene en estado interno oculto hasta que tiene lugar el enésimo desencadenamiento. |
partición : ('T -> bool) -> IObservable<'T> -> IObservable<'T> * IObservable<'T> |
Devuelve dos objetos observables que dividen las observaciones del origen por la función especificada. El primero desencadenará las observaciones de los valores para los que el predicado devuelva true. El segundo desencadenará las observaciones de los valores para los que el predicado devuelva false. El predicado se ejecuta una vez para cada observador suscrito. Ambos objetos observables también propagarán todas las observaciones de error procedentes del origen y se completarán cuando se complete el origen. |
scan : ('U -> 'T -> 'U) -> 'U -> IObservable<'T> -> IObservable<'T> |
Devuelve un objeto observable que, para cada observador, asigna un elemento de estado y aplica la función acumulativa especificada a valores sucesivos procedentes de la entrada. El objeto devuelto desencadenará las observaciones de cada valor de estado calculado, excepto el valor inicial. El objeto devuelto propagará todos los errores procedentes del origen y se completará cuando se complete el origen. |
split : ('T -> Choice<'U1,'U2>) -> IObservable<'T> -> IObservable<'U1> * IObservable<'U2> |
Devuelve dos objetos observables que dividen las observaciones del origen por la función especificada. El primero desencadenará las observaciones para las que el divisor devuelva Choice1Of2. El segundo desencadenará las observaciones y para las que el divisor devuelva Choice2Of2. El divisor se ejecuta una vez para cada observador suscrito. Ambos objetos observables propagarán todas las observaciones de error procedentes del origen y se completarán cuando se complete el origen. |
subscribe : ('T -> unit) -> IObservable<'T> -> IDisposable |
Crea un observador que se suscribe al objeto observable especificado y llama a la función indicada para cada observación. |
Ejemplo
En el ejemplo de código siguiente se muestra cómo usar los objetos observables. La clase ObserverSource definida en este ejemplo es una clase reutilizable de uso general que se puede usar como origen de eventos observables. Aquí se muestran varios ejemplos de uso de algunas de las funciones de este módulo; para las funciones que no se muestran aquí, puede consultar los ejemplos de código en Control.Event (Módulo de 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)
Plataformas
Windows 7, Windows Vista SP2, Windows XP SP3, Windows XP x64 SP2, Windows Server 2008 R2, Windows Server 2008 SP2, Windows Server 2003 SP2
Información de versiones
Runtime de F#
Se admite en las versiones: 2.0, 4.0
Silverlight
Se admite en la versión: 3
Vea también
Referencia
Microsoft.FSharp.Control (Espacio de nombres de F#)
Historial de cambios
Fecha |
Historial |
Motivo |
---|---|---|
Octubre de 2010 |
Se ha agregado un ejemplo de código. |
Mejora de la información. |