Skip to content

Consider revisiting this with the current decorator proposal #9

@Jamesernator

Description

@Jamesernator

Since the decorator proposal changed to a hook-like approach, it's more extensible to more syntax. I think it would be worth revisiting this proposal by defining some decorators that hook into await.

For example a task library might look something like:

class Task {
    static iterator = Symbol('iterator');

    #initialize;
    constructor(initialize) {
        this.#initialize = initialize;
    }

    subscribe(subscriber) {
        let settled = false;
        const resolve = (value) => {
            if (settled) {
                 return;
            }
            settled = true;
            subscriber.value(value);
        }

        const reject = (error) => {
            if (settled) {
                return;
            } 
            settled = true;
            subscriber.error(error);
        }

        const cancel = this.#initialize(resolve, reject);

        return {
            unsubscribe() {
                if (settled) {
                    return;
                }
                settled = true;
                cancel();
            }
        }
    }
}

decorator @task {
  @coroutine({
    getAsyncIterator: value => value[Task.iterator](),
    onCall: (coroutine, asyncLocalState) => {
      const task = new Task((resolve, reject) => {
        asyncLocalState.resolve = resolve;
        asyncLocalState.reject = reject; 
        return () => asyncLocalState.currentSubscription?.unsubscribe();
      });
      coroutine.continue();
      return task;
    },
    onAwait: (coroutine, value, asyncLocalState) => {
      asyncLocalState.currentSubscription = value.subscribe({
        value: value => coroutine.continue(value),
        error: error => coroutine.throw(value),
      });
    },
    onThrow: (coroutine, error, asyncLocalState) => {
      asyncLocalState.reject(error);
    },
    onReturn: (coroutine, value, asyncLocalState) => {
      asyncLocalState.resolve(value);
    },
  })
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions