Rewrite with working async
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
// The drivers of async fns and generators
|
||||
//
|
||||
// The compiler lowers each async fn and generator to a coroutine (see
|
||||
// compiler/src/transform/async.rs): a step closure, which runs the body until
|
||||
// it suspends or returns, and an object `co`:
|
||||
//
|
||||
// { __proto__: <a proto below>, step, value, awaiting, result, done }
|
||||
//
|
||||
// A yield puts its value in `value`, an await puts its promise in `awaiting`,
|
||||
// and a return puts its value in `result` and sets `done`. The fn returns
|
||||
// `co.start()`. Only these drivers differ between the kinds
|
||||
//
|
||||
// Not supported yet: `throw()` on a generator, and `finally` blocks in
|
||||
// `return()`, which need exceptions
|
||||
|
||||
// A generator's object is `co` itself
|
||||
const __GeneratorProto = {
|
||||
// The body runs up to its `initial_yield`, after its params
|
||||
start() {
|
||||
this.step(undefined);
|
||||
return this;
|
||||
},
|
||||
|
||||
next(input) {
|
||||
if (this.done) return { value: undefined, done: true };
|
||||
|
||||
this.step(input);
|
||||
|
||||
if (this.done) return { value: this.result, done: true };
|
||||
return { value: this.value, done: false };
|
||||
},
|
||||
|
||||
return(value) {
|
||||
this.done = true;
|
||||
return { value: value, done: true };
|
||||
},
|
||||
};
|
||||
|
||||
// An async fn returns a promise, which its return fulfils. A rejected await
|
||||
// rejects it, and the rest of the body does not run, as an uncaught throw at the
|
||||
// await would
|
||||
const __AsyncProto = {
|
||||
// The body runs up to its first await, in the call
|
||||
start() {
|
||||
const promise = new Promise(undefined);
|
||||
this.run(promise);
|
||||
return promise;
|
||||
},
|
||||
|
||||
run(promise) {
|
||||
this.step(undefined);
|
||||
|
||||
if (this.done) __resolve(promise, this.result);
|
||||
else this.awaiting.then(() => this.run(promise), (reason) => __reject(promise, reason));
|
||||
},
|
||||
|
||||
// What an await waits on: a promise as it is, any other value as a fulfilled one.
|
||||
// The step reads the value from it when it resumes
|
||||
toPromise(x) {
|
||||
return __is_promise(x) ? x : Promise.resolve(x);
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user