0

I have this Queue class (not the real implementation, but it exemplifies my point):

class Queue {
    constructor() {
        this._arr = [];
    }

    async push(elem) {
        this._arr.push(elem);
    }

    async pop() {
        return this._arr.pop();
    }

    *[Symbol.asyncIterator]() {
        do {
            let res = await this.pop(); // here is the problem
            if (res) yield res;
        } while (res);
    }
}

It's just a wrapper for a Javascript Array with the exception that its methods return a Promise.

What I want to do is to yield conditionally based on the return value of the pop() method, which I cannot do because await is not a valid operation inside an asyncIterator generator function.

I thought about having a flag which is set in the previous iteration:

*[Symbol.asyncIterator]() {
    let continue = true;
    do {
        yield this.pop().then(v => {
            if (!v) continue = false;
            return v
        });
    } while (continue);
}

But this would still return a undefined value in the last execution of pop().

I could handle this in the calling code by checking for a undefined value as a signal of the end of the iteration, but I was wondering if there was a better approach at tackling this problem.

1
  • For a real queue implementation maybe have a look at this. It also implements [Symbol.asyncIterator]() fittingly, without any generator function. Commented Apr 9, 2021 at 1:41

1 Answer 1

1

You can use an async generator function (MDN docs missing, but see e.g. this article) for the implementation of the [Symbol.asyncIterator]() method:

async *[Symbol.asyncIterator]() { /*
^^^^^ */
    while (this._arr.length) {
        yield await this.pop(); // no longer a problem
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Ahh, the simplicity. I knew something like this existed somewhere. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.