• Modules
    • By category
    • By name
    • Most popular
    • Most downloaded
    • Repository
  • Register
  • Log in
  • Help
    • Start using Ceylon Herd
    • Publish your first module
    • Module publishing guidelines
    • All about Ceylon
    • Keyboard Shortcuts

    • s Focus search module bar
      ? Open this information panel
      j Move selection down
      k Move selection up
      enter Open current selection
Module info
Name
FroMage / ceylon.promise / 1.3.0
Ceylon Promise Platform Module
Category SDK

The Ceylon SDK

Backends JVM JavaScript
Maven coordinates
Compatible Ceylon release JVM: 1.2.x, 1.3.x (latest)
JavaScript: 1.2.1, 1.2.2, 1.3.x (latest)
Published Sep 15, 2016
Stats Downloads (JVM): 273
Downloads (JS): 67
Source downloads: 355
Authors Julien Viet
License Apache Software License
Description

Support for promises. If an operation cannot return a value immediately without blocking, it may instead return a promise of the value. A promise is an object that represents the return value or the thrown exception that the operation eventually produces. Such an operation is sometimes called a long-running operation.

This module provides following abstractions:

  • The Completable interface abstracts objects which promise one or more values, accommodating the possibility of failure.
  • The Completion interface abstracts Completables that may be combined to form a compound promise that produces multiple values.
  • The Promise class, a Completable that produces a single value, or fails.
  • The Deferred class, providing support for operations which return instances of the Promise interface.
  • The ExecutionContext class abstracts the concurrency of the runtime running the promises. The JVM runtime uses a threadpool, the JavaScript runtime uses the setTimeout function. The defineGlobalExecutionContext can be use to change the default context

Promises

A Promise exists in one of three states:

  • In the promised state, the operation has not yet terminated.
  • In the fulfilled state, the operation has produced a value.
  • In the rejected state, the operation has terminated without producing a value. This situation is represented as an exception.

The method Promise.completed allows interested parties to be notified when the promise makes a transition from the promised state to the fulfilled or the rejected state:

Promise<Document> promise = queryDocumentById(id);
promise.completed {
    (d) => print("Got the document: " + d.title);
    (e) => print("Document was not received: " + e.message);
};

The first function is called the onFulfilled callback and the second function is called the onRejected callback. The onRejected function is always optional.

Returning promises

A Deferred object is a factory that provides an instance of the Promise class and manages its lifecycle, providing operations to force its transition to a fulfilled or rejected state.

The instance of Deferred should remain private to the long-running operation, only the Promise should be exposed to the caller.

The Promise of a deferred can be retrieved from its promise field:

value deferred = Deferred<String>();
return deferred.promise;

The Deferred object implements the Completable interface which provides two methods for controlling the state of the promise:

  • fulfill() fulfills the promise with a value, and
  • reject() rejects the promise with a reason of type Throwable.

For example:

value deferred = Deferred<String>();
void doOperation() {
    try {
        String val = getValue();
        deferred.fulfill(val);
    }
    catch (Throwable e) {
        deferred.reject(e);
    }
}

Chaining promises

When chaining is needed the method Completion.map should be used instead of the Completion.completed method.

When invoking the Completion.map method the onFulfilled and onRejected callbacks can return a value. The map() method returns a new promise that will be fulfilled with the value of the callback. This promise will be rejected if the callback invocation fails.

For example:

Promise<Integer> promiseOfInteger = newPromiseOfInteger();
Promise<String> promiseOfString = promiseOfInteger.map(Integer.string);
promiseOfString.map((s) => print("Completed with " + s));

Or, more concisely:

newPromiseOfInteger()
    .map(Integer.string)
    .map((s) => print("Completed with " + s));

Composing promises

Promises can be composed into a single promise that is fulfilled when every one of the individual composed promises is fulfilled. If one of the promise is rejected then the composed promise is rejected.

Promise<String> promiseOfString = newPromiseOfString();
Promise<Integer> promiseOfInteger = newPromiseOfInteger();
(promiseOfString.and(promiseOfInteger)).completed {
    (i, s) => print("All fulfilled");
    (e) => print("One failed");
};

Notice that:

  • The order of the parameters in the callback is in reverse order in which the corresponding promises are chained.
  • The return type of combined promise is not Promise but Completion.

The onComplete() method

The onComplete() method of a promise allows a single callback to be notified when the promise is fulfilled or rejected.

Promise<Document> promise = queryDocumentById(id);
promise.onComplete {
    void (Document|Throwable result) {
        switch (result)
        case (is Document) { print("Fulfilled"); }
        case (is Throwable) { print("Rejected"); }
    };
 };

Promise.onComplete is most useful for implementing a finally clause in a chain of promises.

Feeding with a promise

Deferred can be transitioned with a promise instead of a value:

Deferred<String> deferred = getDeferred();
Promise<String> promise = getPromise();
deferred.fulfill(promise);

Similarly, with Promise.flatMap, a callback may return a promise instead of a value:

Deferred<String> deferred = Deferred<String>();
Promise<String> promise2 = promise.flatMap((s) => deferred.promise);

Thread safety

The implementation is thread safe and uses a non blocking algorithm for maintaining the state of a Deferred object.

Relationship to the A+ specification

This module is loosely based upon the A+ specification, with the following differences:

  • The then() method is split between Completion.map that returns an object and Completion.flatMap that can return a Promise
  • The Promise Resolution Procedure is implemented for objects or promises but not for thenables since that would require a language with dynamic typing.
Dependencies
All backends JVM JavaScript
ceylon.language/1.3.0
java.base/7 JDK
Usage
  • Import
 import ceylon.promise "1.3.0";
Module links Members
Imported By
Home
Code repository
Issue tracker
Browse
Download .car
Download .js
Download source archive
Download module documentation
View API documentation

Ceylon Herd v1.24 Copyright 2012-2021 Red Hat. About