简体   繁体   中英

Wait for an async operation inside asyncIterator generator function

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.

You can use an async generator function (MDN docs missing, but see eg 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
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM