Here are some tools and guidance for writing specifications that create, accept, or manipulate promises.
When writing such specifications, it's convenient to be able to refer to common promise operations concisely. We define here a set of shorthands that allow you to do so.
"A newly-created promise object" gives a new, initialized-but-unresolved promise object to manipulate further.
"A promise resolved with x
" is shorthand for the result of creating a promise p
, then calling Resolve(p, x)
.
"A promise rejected with x
" is shorthand for the result of creating a promise p
, then calling Reject(p, x)
.
"x
cast to a promise" is shorthand for the result of ToPromise(x)
.
"Resolve p
with x
" is shorthand for calling Resolve(p, x)
.
"Reject p
with r
" is shorthand for calling Reject(p, r)
.
"Transforming p
with onFulfilled
and onRejected
" is shorthand for the result of Then(p, onFulfilled, onRejected)
.
"Racing p1
, p2
, p3
, …" is shorthand for the result of Promise.race([p1, p2, p3, …])
, using the initial value of Promise.race
.
"Racing iterable
" is shorthand for the result of Promise.race(iterable)
, using the initial value of Promise.race
.
"Waiting for all of p1
, p2
, p3
, …" is shorthand for the result of Promise.all([p1, p2, p3, …])
, using the initial value of Promise.all
.
"Waiting for all of iterable
" is shorthand for the result of Promise.all(iterable)
, using the initial value of Promise.all
.
In general, when an argument is expected to be a promise, you should also allow thenables and non-promise values by casting the argument to a promise before using it.
Promise rejections should always be instances of the ECMAScript Error
type, just like synchronously-thrown exceptions should always be instances of Error
as well.
Promise-returning functions should never synchronously throw errors, since that would force duplicate error-handling logic on the consumer. Even argument validation errors are not OK. Instead, they should return rejected promises.
assertIsObject
is a very simple function that returns a fulfilled promise if passed an object, and a rejected one if it is not an object.
- If
Type(x)
isObject
, return a promise resolved withundefined
. - Otherwise, return a promise rejected with a
TypeError
having message"Not an object!"
.
environment.ready
is a property that signals when some part of some environment becomes "ready," e.g. a DOM document.
- Let
Environment.ready
be a newly-created promise. - When/if the environment becomes ready, resolve
Environment.ready
withundefined
. - When/if the environment fails to load, reject
Environment.ready
with anError
instance explaining the load failure.
delay
is a function that returns a promise that will be fulfilled in ms
milliseconds.
- Let
p
be a newly-created promise. - In
ms
milliseconds, resolvep
withundefined
. - Return
p
.
addDelay
is a function that adds an extra ms
milliseconds of delay between promise
settling and the returned promise settling.
- Let
p
be a newly-created promise. - Let
onFulfilled(v)
be a function that waitsms
milliseconds, then resolvesp
withv
. - Let
onRejected(r)
be a function that waitsms
milliseconds, then rejectsp
withr
. - Let
castToPromise
be the result of castingpromise
to a promise. - Transform
castToPromise
withonFulfilled
andonRejected
. - Return
p
.