Looking for ways to make async and await less specific in ES.
Thought:
-
async
causes its operand to iterate and become aPromise
-
let
result
be a newPromise
-
let
operand
be the value immediately followingasync
-
if
operand
is an instance ofIterator
1. if theIteratorComplete(operand)
is not true- let
iterationResult
be the result ofIteratorNext(operand)
- fullfill
result
with theiterationResult
1. else fullfillresult
withundefined
- let
-
else fulfill
result
withoperand
-
return
result
-
await
acts like a self referentialyield
that returns aPromise
it will not resume until a non-await
value is generated. -
let
generator
be the activeGenerator
instance -
let
operand
be the value immediately followingawait
-
let
operandPromise
bePromise.cast(operand)
-
let
result
beundefined
-
if
generator[@AwaitingPromise]
does not exist 1. letgenerator[@AwaitingPromise]
be a newPromise
1. letresult
begenerator[@AwaitingPromise]
-
else 1. if
generator[@AwaitingContinuation]
does not exist- let
generator[@AwaitingContinuation]
be a new unique value 1. letresult
begenerator[@AwaitingContinuation]
- let
-
let
finalPromise
begenerator[@AwaitingPromise]
-
when
operandPromise
fulfills 1. setup atry
guard 1. letiteration
be the resultgenerator.next
with the corresponding value 1. if something is thrown- delete
generator[@AwaitingPromise]
andgenerator[@AwaitingContinuation]
- reject
finalPromise
with the corresponding value 1. ifiteration.done
oriteration.value
is notgenerator[@AwaitingContinuation]
- delete
generator[@AwaitingPromise]
andgenerator[@AwaitingContinuation]
- fulfill
finalPromise
withiteration.value
- delete
-
when
operandPromise
rejects 1. callgenerator.throw
with the corresponding value -
perform
yield result
What brought this up:
function* doLogin(req) {
// causes a promise (finalPromise) to be yielded
//
// operand is treated as a promise (innerPromise)
// continues to execute after the innerPromise resolves
// does not resolve finalPromise
var session = await login(req);
// we are already awaiting so we continue
//
// operand is treated as a promise (innerPromise)
// continues to execute after the innerPromise resolves
// does not resolve finalPromise
await audit(session);
// non-promises will just continue execution
// since their promise resolves immediately
// this will however split up work across ticks (useful)
var one_two_three = await 123;
// this is not a value we will be awaiting
// resolve this as the finalPromise value
return session;
}
// meh usage
//
// no await
(async doLogin(req)).then(function (session) {
// we got a session!
}).catch(function (e) {
// we failed to login, or we failed the audit
});
// epic usage
//
// assumes script is running in a generator that supports await
try {
var session = await async doLogin(req);
// we got a session!
}
catch (e) {
// we failed to login, or we failed the audit
}