Standard Library
class Promise<T>
A value that arrives later.
since 0.1.0-alpha.1linuxwindows
Overview
A promise starts out pending and is settled once by resolve. await promise waits, without blocking the rest of the program, until the promise is ready and then gives its value; if the promise is already ready, await returns at once. Any function may await, because there is no separate async function type: a function that returns a Promise<T> is simply the asynchronous form. A promise that only signals completion is a Promise<void>, resolved with resolve(None).
Create a pending promise with Promise() and a ready one with Promise(value). Something else, usually a timer or a callback, calls resolve when the value exists.
Description
Promise<T> is an ordinary class. The language gives it no special rules and wraps nothing for
you: a function that is meant to produce a value later must return a real Promise, and the
body of such a function is responsible for resolving it. await is the one operation the
language treats specially, and it only needs something promise-shaped to wait on.
A promise is created in one of two states.
Promise()is pending: it holds no value yet.isReady()isfalse.Promise(v)is pre-resolved: it already holdsv.isReady()istrue.
resolve(v) stores a value and marks the promise ready. get() reads the stored value, and
then(cb) registers a callback to run with the value. If the promise is already ready, then
runs the callback immediately; otherwise the callback runs inside the call to resolve that
settles the promise.
Pending and pre-resolved promises
Promise<int> ready = Promise(42);
console.writeln(ready.isReady());
console.writeln(ready.get());
Promise<string> later = Promise();
console.writeln(later.isReady());
later.then((s) => console.writeln("then saw ${s}"));
console.writeln("resolving");
later.resolve("hello");
console.writeln(later.isReady());
true
42
false
resolving
then saw hello
true
A promise whose only job is to say "this has finished" is a Promise<void>. Resolve it with the
unit value, None: done.resolve(None). A pre-resolved completion promise is Promise(None).
Awaiting a Promise<void> waits but yields no usable value.
Rules
- A function that returns a promise must return a real
Promise; there is no implicit wrapping of plain values and noasynckeyword. await exprunwraps aPromise<T>to aT. Anawaiton a promise that is already ready does not suspend at all. Seelang.awaitfor what runs while anawaitwaits.thenholds one callback. Callingthenon a pending promise a second time replaces the first callback instead of adding to it.- Resolve a promise once. Resolving again is not an error, but it overwrites the stored value
(and runs a pending
thencallback again), so treat a secondresolveas a bug. thenruns its callback synchronously, in the context of whoever resolves the promise. If you need to wait in straight-line code, useawait.
Examples
A function that returns a promise, resolved by a timer and consumed with await:
Awaiting a promise resolved by a timer
Promise<int> square(int n) {
Promise<int> p = Promise();
std::sysTimerStart(5, 0, (t) => p.resolve(n * n));
return p;
}
int sq = await square(7);
console.writeln("7 squared is ${sq}");
Promise<int> already = Promise(9);
console.writeln(await already);
console.writeln(await 5);
7 squared is 49
9
5
The last line shows that await on a value that is not a promise yields the value unchanged.
Notes
A Worker<T>, the handle returned by std::spawn, is itself a Promise<T>, so joining a
worker is just an await.
Examples
Waiting for a value that a timer provides
Promise<int> done = Promise();
done.then((v) => { console.writeln("then saw ${v}"); });
console.writeln("ready? ${done.isReady()}");
done.resolve(7);
console.writeln("ready? ${done.isReady()}");
Promise<int> later = Promise();
std::sysTimerStart(10, 0, (n) => { later.resolve(99); });
int v = await later;
console.writeln("awaited ${v}");
ready? false
then saw 7
ready? true
awaited 99
Constructors
new
new()Create a pending promise.
The promise is not ready until something calls resolve on it.
Examples
Pending and already-resolved promises
Promise<int> pending = Promise();
console.writeln(pending.isReady());
Promise<int> done = Promise(5);
console.writeln(done.isReady());
console.writeln(done.get());
false
true
5
new(T v)Create a promise that is already resolved with a value.
Awaiting it returns the value at once, and then runs its callback immediately.
Parameters
- v
- The value the promise holds.
Fields
ready
bool readyWhether the promise has been settled. Prefer isReady.
value
T valueThe settled value; meaningful only once the promise is ready. Prefer get or await.
Methods
get
get() -> TRead the promise's value without waiting.
The value is only meaningful after the promise is ready; check isReady first, or use await to wait for it.
Returns
The settled value.
Examples
Promise<int> p = Promise(42);
if (p.isReady()) {
console.writeln(p.get());
}
42
isReady
isReady() -> boolTell whether the promise has been settled.
Returns
true once the promise has been resolved, otherwise false.
Examples
Promise<int> p = Promise();
console.writeln(p.isReady());
p.resolve(1);
console.writeln(p.isReady());
false
true
resolve
resolve(T v) -> voidSettle the promise with a value.
The promise becomes ready, anything awaiting it wakes up, and the callback given to then runs with the value. For a Promise<void> resolve with None.
Parameters
- v
- The value to settle the promise with.
Examples
Promise<string> p = Promise();
p.then((s) => { console.writeln("got ${s}"); });
p.resolve("hello");
console.writeln(p.get());
Promise<void> signal = Promise();
signal.resolve(None);
console.writeln(signal.isReady());
got hello
hello
true
then
then((T) => void cb) -> voidRun a callback with the value once the promise is ready.
If the promise is already ready the callback runs immediately. Otherwise it runs inside resolve, in the context of whoever resolves the promise. A promise keeps only one callback: registering a second one before the promise is resolved replaces the first.
Parameters
- cb
- The function to call with the value.
Examples
Promise<int> p = Promise();
p.then((v) => { console.writeln("first ${v}"); });
p.then((v) => { console.writeln("second ${v}"); });
p.resolve(1);
p.then((v) => { console.writeln("late ${v}"); });
second 1
late 1
See also
- Worker — The handle to a value that another worker is computing.
- awaitTimeout — Wait for a promise, but give up after a time limit.
- Timer — A source of ticks on the event loop.
- InStream — The reading end of a stream: a queue of values of type
Tthat something else produces.