promise
A promise is a first-class value standing for a result that is not
available yet. It is in one of four states — pending, fulfilled
with a value, rejected with a reason, or cancelled — and it
settles at most once. Cancelled is a negative settlement (await and
then treat it like a rejection) that promise_status() reports as 3
so a cancellation can be told from a fault.
promise p = promise_create(); // pending
promise_resolve(p, 42); // fulfilled with 42
promise_status(p); // 1
promise_result(p); // 42
Promises are produced by async functions, by the
promise efuns, and by the promise forms of the callback efuns
(call_out(delay), async_read(path), external_start(index, args),
external_run(handle), ...). They are consumed with
await, or with promise_then() / promise_catch() handlers.
Value semantics
Like objects and functions, a promise is a reference with identity, not a container:
| operation | behaviour |
|---|---|
p == q | true only for the same promise |
| mapping key | keyed by identity |
copy(p) | the same promise, not a copy |
save_object() | not serialisable; saves as 0 |
typeof(p) | "promise" |
sprintf("%O", p) | PROMISE( fulfilled: 42 ) |
promisep(x) tests the type. A promise is reference-counted: when the last
reference goes away it is reclaimed, and anything awaiting it simply never
resumes — the same as an abandoned callback.
Typed promises: promise<T>
The type may name its payload, which is what a call site of an async
function is given:
async int fetch(); // returns promise<int>
promise<int> p = fetch();
int n = await p; // await yields the payload type
promise<int> * is an array of promises; promise<int *> is a promise of
an array — * keeps its ordinary meaning and the two compose. A promise of
a promise is not representable, matching the runtime, where resolving a
promise with a promise adopts it rather than nesting.
Bare promise is promise<mixed>: it accepts any payload, which is what
promise_create() and the promise-form efuns return.
The payload type is a declaration, not a measurement. An async int f()
whose body returns a mixed holding a string still produces a promise
tagged int; nothing re-checks it at settle time.
Errors
- Settling a promise that is already settled is an error — including one whose fate is already committed to a pending adoption.
- Settling a promise returned by an
asyncfunction is an error: it is the body's result channel, and the body settles it. Doing so would discard whatever the body returns without stopping it running. The refusal is limited to those: a promise frompromise_create(),promise_then(), or the promise form of a callback efun stays settleable — settling one just means the driver's later result is dropped when it arrives. promise_result()on a pending promise is an error.- A rejection nothing ever observes is reported to the debug log when the promise is deallocated, naming where it was rejected.
See also
asyncfunctions,awaitandacatch— the syntax- The async/await execution model — scheduling, suspension and resource limits
promise_create,promise_resolve,promise_reject,promise_then,promise_catch,promise_status,promise_result,promisep,async_yield,async_info- combinators:
promise_all,promise_any,promise_race,promise_all_settled promise_cancel— ask anasyncbody to give up at its nextawait