Promise

Namespace: global

Declared types

TypeDescription
PromiseBuilder

A builder to provide promise Computation Expression support.

The CE is available via promise { ... }

Example

let double (value : int) =
    promise {
        return value * 2
    }
SettledStatus
SettledValue<'T>

Values and functions


val create :
    f      : ('T -> unit) -> (exn -> unit) -> unit 
           -> Promise<'T>

Create a promise from a function

Example

let write (path: string) (content: string) =
    Promise.create (fun resolve reject ->
        Node.Api.fs.writeFile(path, content, (fun res ->
            match res with
            | Some res -> reject (res :?> System.Exception)
            | None -> resolve ()
        ))
    )

Parameters

f : ('T -> unit) -> (exn -> unit) -> unit

Function used to create the promise, it receives two other function parameters:

  • success : called when the promise is resolved
  • fail : called when the promise is rejected

Returns

The promise created by the function


val sleep :
    ms    : int 
          -> Promise<unit>

Create a promise which wait X ms before resolving.

Example

// Do something
doSomething ()
// Sleep for 1 second
|> Promise.sleep 1000
// Do another thing
|> Promise.map (fun _ ->
    doAnotherThing ()
)
|> Promise.map ...

Parameters

ms : int
Number of milliseconds to wait

Returns

A delayed promise


val lift :
    a    : 'T 
         -> Promise<'T>

Create a promise (in resolved state) with supplied value.

Example

Promise.lift {| Firstname = "John" |}
|> Promise.map (fun user ->
    console.log $"Hello, %s{user.Firstname}"
    // Expected output: "Hello, John"
)
|> Promise.map ...

Parameters

a : 'T
Value to return

Returns

Returns a promise returning the supplied value


val reject :
    reason : exn 
           -> Promise<'T>

Creates promise (in rejected state) with supplied reason.

Example

Promise.reject (Exception "User not found")
|> Promise.map (fun _ ->
    // This promise is skipped
)
|> Promise.catch (fun error ->
    console.error $"An error ocurred: %s{error.Message}"
    // Expected output: "An error ocurred: User not found"
)
|> Promise.map ...

Parameters

reason : exn
Reason to return

Returns

Return a promise in a rejected state


val bind :
    a    : 'T1 -> Promise<'T> ->
    pr   : 'T1                
         -> Promise<'T2>

Bind a value into a promise of a new type.

Example

Promise.lift {| Firstname = "John" |}
|> Promise.bind (fun user ->
    // Do something with user and returns a promise
    Promise.create (fun resolve reject ->
        resolve $"Hello, %s{user.Firstname}"
    )
)
|> Promise.map (fun message ->
    console.log message
    // Expected output: "Hello, John"
)
|> Promise.map ...

Parameters

a : 'T1 -> Promise<'T>

A function that takes the value of type T1 and transforms it into a promise of type T2.

pr : 'T1
The input promise

Returns

A promise of the output type of the binder.


val map :
    a   : 'T1 -> 'T2 ->
    pr  : 'T1        
        -> Promise<'T2>

Map a value into another type, the result will be wrapped in a promise for you.

Example

Promise.lift {| Firstname = "John" |}
|> Promise.map (fun user ->
    user.Firstname
) // Returns a Promise<string> with the value "John"
|> Promise.map ...

Parameters

a : 'T1 -> 'T2
A function to apply to the result of the input promise.
pr : 'T1
The input promise

Returns

A promise after applying the mapping function


val iter :
    a    : 'T -> unit ->
    pr   : 'T         
         -> unit

Call a function with the result of a promise and stop the promise chain.

This is equivalent to Promise.map ... |> ignore

Example

fetchUser ()
|> Promise.iter (fun user ->
    console.log "User firstname is user.Firstname"
) // unit

Parameters

a : 'T -> unit
A function to apply to the result of the input promise
pr : 'T
The input promise

val tap :
    fn  : 'T -> unit ->
    a   : 'T         
        -> Promise<'T>

This is an identity function, it calls the given function and return the promise value untouched.

Example

fetchUser ()
|> Promise.tap (fun user ->
    // Do something
    console.log "The user has been received"
)
|> Promise.map (fun user ->
    // user value is available here untouched
)

Parameters

fn : 'T -> unit
A function to call after receiving the receiving of the input promise
a : 'T
The input promise

Returns

A promise of the same type as the input promise


val catch :
    fail  : exn -> 'T ->
    pr    : 'T        
          -> Promise<'T>

Handle an errored promise allowing you pass a return value.

This version of catch expects a function returning just 'T, as opposed to Promise<'T>. If you need to return Promise<'T>, use catchBind.

Example

Promise.create (fun resolve reject ->
    reject (System.Exception "User not found")
)
|> Promise.catch (fun error ->
    // Log the error
    console.error error
    // Do something to recover from the error
    Error error.Message
)
|> Promise.map ...

Parameters

fail : exn -> 'T
Function to call if the input promise fail
pr : 'T
The input promise

Returns

A promise which result of the call of fail


val catchBind :
    fail      : exn -> Promise<'T> ->
    pr        : 'T                 
              -> Promise<'T>

Handle an errored promise allowing to call a promise.

This version of catch expects a function returning Promise<'T> as opposed to just 'T. If you need to return just 'T, use catch.

Example

Promise.create (fun resolve reject ->
    reject (System.Exception "User not found")
)
|> Promise.catchBind (fun error ->
    // Recover from the error, here we call another promise and returns it's result
    logErrorToTheServer error
)
|> Promise.map ...

Parameters

fail : exn -> Promise<'T>
Function to call if the input promise fail
pr : 'T
The input promise

Returns

A promise which is the result of the fail function


val catchEnd :
    fail     : exn -> unit ->
    pr       : 'T          
             -> unit

Used to catch errors at the end of a promise chain.

Example

Promise.create (fun resolve reject ->
    reject (System.Exception "User not found")
)
|> Promise.map (fun _ ->
    // ...
)
|> Promise.map (fun _ ->
    // ...
)
|> Promise.catchEnd (fun error ->
    // ...
) // Returns unit

Parameters

fail : exn -> unit
Fuction to call if the input promise fail
pr : 'T
The input promise

val either :
    success : 'T1 -> 'T2 ->
    fail    : exn -> 'T2 ->
    pr      : 'T1        
            -> Promise<'T2>

A combination of map and catch, this function applies the success continuation when the input promise resolves successfully, or fail continuation when the input promise fails.

Example

somePromise
|> Promise.either
    (fun x -> string x)
    (fun err -> Promise.lift err.Message)
|> Promise.map ...

Parameters

success : 'T1 -> 'T2
Function to call if the input promise succeeds
fail : exn -> 'T2
Function to call if the input promise fail
pr : 'T1
The input promise

Returns

A new promise which is the result of calling success if pr succeedes, or of fail if pr failed


val eitherBind :
    success    : 'T1 -> Promise<'T> ->
    fail       : exn -> Promise<'T> ->
    pr         : 'T1                
               -> Promise<'T2>

A combination of bind and catchBind, this function applies the success continuation when the input promise resolves successfully, or fail continuation when the input promise fails.

Example

somePromise
|> Promise.eitherBind
    (fun x -> string x |> Promise.lift)
    (fun err -> Promise.lift err.Message)
|> Promise.map ...

Parameters

success : 'T1 -> Promise<'T>
Binder function to call if the input promise succeeds
fail : exn -> Promise<'T>
Binder function to call if the input promise fail
pr : 'T1
The input promise

Returns

A new promise which is the result of calling success if pr succeedes, or of fail if pr failed


val eitherEnd :
    success   : 'T -> unit  ->
    fail      : exn -> unit ->
    pr        : 'T          
              -> unit

Same as Promise.either but stopping the promise execution.

Example

somePromise
|> Promise.eitherEnd
    (fun x -> string x)
    (fun err -> Promise.lift err.Message)

Parameters

success : 'T -> unit
Binder function to call if the input promise succeeds
fail : exn -> unit
Binder function to call if the input promise fail
pr : 'T
The input promise

val start :
    pr    : 'T 
          -> unit

Start a promise.

Fake starting a promise. It is faking it because promise are hot meaning they execute directly after their creation.

Promise.start is equivalent to promise |> ignore

Example

myPromise
|> Promise.start

Parameters

pr : 'T
The input promise

val tryStart :
    fail     : exn -> unit ->
    pr       : 'T          
             -> unit

Same as Promise.start but forcing you to handle the rejected state.

Example

myPromise
|> Promise.tryStart
    (fun error ->
        // Do something on error
    )

Parameters

fail : exn -> unit
Function to apply if the promise fail
pr : 'T
The input promise

val Parallel :
    pr       : Promise<'T> 
             -> Promise<'T[]>

Takes a sequence of promises as an input, and returns a single Promise that resolves to an array of the results of the input promises.

Example

let p1 =
    promise {
        do! Promise.sleep 100
        return 1
    }
let p2 =
    promise {
        do! Promise.sleep 200
        return 2
    }
let p3 =
    promise {
        do! Promise.sleep 300
        return 3
    }

Promise.Parallel [p1; p2; p3]
|> Promise.map (fun res ->
    // res = [|1; 2; 3 |]
)
|> Promise.map ...

Parameters

pr : Promise<'T>
A list of promise to wait for

Returns

Return a new promise returning an array containing all the promise result


val all :
    pr  : Promise<'T> 
        -> Promise<'T[]>

Takes a sequence of promises as an input, and returns a single Promise that resolves to an array of the results of the input promises.

Example

let p1 =
    promise {
        do! Promise.sleep 100
        return 1
    }
let p2 =
    promise {
        do! Promise.sleep 200
        return 2
    }
let p3 =
    promise {
        do! Promise.sleep 300
        return 3
    }

Promise.all [p1; p2; p3]
|> Promise.map (fun res ->
    // res = [|1; 2; 3 |]
)
|> Promise.map ...

Note: If you need to return mixed types you can use boxing and unboxing

Example

let users =
    promise {
        let! users = fetchUsers ()
        return box users
    }
let posts =
    promise {
        let! posts = fetchPosts ()
        return box posts
    }

Promise.all [p1; p2]
|> Promise.map (fun res ->
    let users = unbox<User list> res.[0]
    let posts = unbox<Post list> res.[1]
    // ...
)

Parameters

pr : Promise<'T>
A list of promise to wait for

Returns

Return a new promise returning an array containing all the promise result


val allSettled :
    pr         : Promise<'T> 
               -> Promise<SettledValue<'T>[]>

The Promise.allSettled function returns a promise that resolves after all of the given promises have either fulfilled or rejected, with an array of objects that each describes the outcome of each promise. It is typically used when you have multiple asynchronous tasks that are not dependent on one another to complete successfully, or you'd always like to know the result of each promise. In comparison, the Promise returned by Promise.all may be more appropriate if the tasks are dependent on each other / if you'd like to immediately reject upon any of them rejecting.

Parameters

pr : Promise<'T>
A list of promise to wait for

val any :
    pr  : Promise<'T> 
        -> Promise<'T>

Promise.any takes an iterable of Promise objects. It returns a single promise that resolves as soon as any of the promises in the iterable fulfills, with the value of the fulfilled promise. If no promises in the iterable fulfill (if all of the given promises are rejected), then the returned promise is rejected with an AggregateError, a new subclass of Error that groups together individual errors.

Parameters

pr : Promise<'T>
A list of promise to wait for

val race :
    pr   : Promise<'T> 
         -> Promise<'T>

The Promise.race method returns a promise that fulfills or rejects as soon as one of the promises in an iterable fulfills or rejects, with the value or reason from that promise.

Parameters

pr : Promise<'T>

val result :
    a      : 'T 
           -> Promise<Result<'T, exn>>

Map the Promise result into a Result type.

Example

Success example
Promise.lift 42
|> Promise.result
|> Promise.map (fun value ->
    // value = Ok 42
)

// Fail example
Promise.reject "Invalid value"
|> Promise.result
|> Promise.map (fun value ->
    // value = Error "Invalid value"
)

Parameters

a : 'T
The input promise

Returns

A promise returning Ok if the input promise succeed, Error if the input promise failed


val mapResult :
    fn        : 'T1 -> 'T2      ->
    a         : Result<'T1 ,'E> 
              -> Promise<Result<'T2, 'E>>

Evaluates to myPromise |> Promise.map (Result.map fn)

Example

Promise.lift 42
|> Promise.result
|> Promise.mapResult (fun value ->
    value + 10
)
|> Promise.map (fun value ->
    // value = Ok 52
)

Parameters

fn : 'T1 -> 'T2
The mapping function
a : Result<'T1 ,'E>
The input promise

Returns

A promise returning the result of applying the mapping function to the input promise result


val bindResult :
    fn         : 'T1 -> Promise<'T> ->
    a          : Result<'T1 ,'E>    
               -> Promise<Result<'T2, 'E>>

Transform the success part of a result promise into another promise.

Example

let multiplyBy2 (value : int) =
    Promise.create (fun resolve reject ->
        resolve (value * 2)
    )

Promise.lift 42
|> Promise.result
|> Promise.bindResult (fun value ->
    multiplyBy2 value
)
|> Promise.map (fun value ->
    // value = Ok 84
)

Parameters

fn : 'T1 -> Promise<'T>
The binder function
a : Result<'T1 ,'E>
The input promise

Returns

Returns a new promise applying to the binder function to it if the input promise succeed


    fn             : 'E1 -> 'E2      ->
    a              : Result<'T ,'E1> 
                   -> Promise<Result<'T, 'E2>>

Evaluates to myPromise |> Promise.map (Result.map fn)

Example

Promise.reject -1
|> Promise.result
|> Promise.mapResultError (fun value ->
    $"%s{value} is not a valid value"
)
|> Promise.map (fun value ->
    // value = Error "-1 is not a valid value"
)

Parameters

fn : 'E1 -> 'E2
A mapper function
a : Result<'T ,'E1>
The input promise

Returns

A promise returning the result of applying the mapper function to the input promise in case of error, otherwise the result of the input promise as it is