简体   繁体   中英

Can generator use async functions?

I am fetching data from backend service, 20 results at a time. I would like to hide this implementation detail and create a generator that would keep returning records for as long as I need them (while they are available).

Naive implementation:

function* getEndlessRecords(fetchingFunction) {
  const batchSize = 20;

  // endless loop:
  for (let offset = 0; true; offset += batchSize) {
    fetchingFunction(offset, batchSize)
      .then(records => {
        for (let i=0; i < records.length; i++) {
          yield records[i]; // THIS DOESN'T WORK!!!
        }
      })
  }
}

(there might be typos - this is simplified code)

I understand why this doesn't work ( yield works on innermost function), however I can't seem to find a nice way to create a generator around the async functions.

Is it possible for generator to consume output from async functions?

As of ES2018, you could use an async generator function :

async function* getEndlessRecords(fetchingFunction) {
  const batchSize = 20;

  // endless loop:
  for (let offset = 0; true; offset += batchSize) {
    const records = await fetchingFunction(offset, batchSize);
    for (let i=0; i < records.length; i++) {
      yield records[i];
    }
  }
}

You'd consume that in an async function using for-await-of (not for-of ):

for await (const value of getEndlessRecords(/*...*/)) {
    // Do something with `value`
}

...or just by calling its next method and awaiting the result:

let g = getEndlessRecords(/*...*/);
let result;
while (!(result = await g.next()).done) {
    console.log(result.value);
}

...or of course, in a non- async function, you'd use then on the result of g.next() .

Prior to ES2018's async generator function syntax, you'd have to hand-code the generator rather than using function* syntax. Doing so arguably- in correctly (not allowing for any extensions to %GeneratorPrototype% ) is fairly easy. Doing so correctly is fairly awkward, since %GeneratorPrototype% doesn't have a publicly-accessible symbol and you have to go discover it.

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