Skip to content

Promise

Lautaro Brasseur edited this page Jun 29, 2018 · 2 revisions

Promise

Promises are used to implement callbacks in async calls. They have type parameters for the returned value and the (potentially) thrown exception.

Promise<Integer, IOException> anAsyncCall(String data) {
    // Do async work..
}

Promise methods return a promise (it might be same or a new one), so you can chain calls.

Getting the result value

You can specify a callback for getting the returned value:

anAsyncCall("Hi1")
        .then(value -> System.out.print("This is an int: " + value));

Catching errors

You can do it in this way:

anAsyncCall("Hi1")
        .capture((e) -> e.printStackTrace())
        .then(value -> System.out.print("This is an int: " + value));

Transforming results

You can transform the returned value:

anAsyncCall("Hi1")
        .map((i) -> i.toString())
        .then(value -> System.out.print("This is an String: " + value));

and you can transform the exception as well

anAsyncCall("Hi1")
        .mapError(e -> new RuntimeException(e))
        .then(value -> System.out.print("This is an String: " + value));

Each time you apply a transformation, the parameterized type of the promise changes to match the transformation result.

Continuations

You can specify chain promise execution. You can do this by providing a callback that executes the continuation for the next promise:

Promise<Integer, IOException> returnsInteger(String data) {
    // Do async call..
}

Promise<String, IOException> returnsString(Integer data) {
    // Do async call..
}

void chaining() {
    returnsInteger("Hi1")
            .continueWith((i) -> returnsString(i))
            .then(value -> System.out.print("This is an String: " + value));
}

If the 2 promises throw different exceptions, you can provide a function for transforming them:

Promise<Integer, IOException> returnsInteger(String data) {
    // Do async call..
}

Promise<String, RuntimeException> returnsString(Integer data) {
    // Do async call..
}

void chaining() {
    returnsInteger("Hi1")
            .continueWith((i) -> returnsString(i),
                    (e) -> new RuntimeException(e))
            .then(value -> System.out.print("This is an String: " + value));
}

Building your own promise

You can use Deferred for this goal:

Promise<Integer, RuntimeException> cusotmAsyncCall() {
    Deferred<Integer, RuntimeException> deferred = Deferred.defer();

    // Exceute async code... for example, a timer
    new Timer().schedule(new TimerTask() {
        @Override
        public void run() {
            // Acoording to the logic, send an error o
            int value = aBusinessMethod();
            if (value > 0) {
                deferred.resolve(value);
            } else {
                deferred.reject(new RuntimeException("Invalid value: " + value));
            }
        }
    }, 1000);

    return deferred.promise();
}

Clone this wiki locally