I figured out that the asynchronous generator pattern is fairly new to JavaScript and only available in Node.js as of version 10. So after I did all that, I can now use the following function to yield multiple similar elements in a web page using Selenium, which uses async/await for many of its functions:
formElements = async function*(containerCss, childCss, defaultCount) {
let countCSS = containerCss + " " + childCss;
let numElements = await countCss(countCSS) || defaultCount;
for (let cIndex = 1; cIndex <= numElements; cIndex++) {
let elementCss = containerCss + ":nth-child(" + cIndex + ") " + childCss;
yield await elmCSS(elementCss);
}
}
This function works fine as an asynchronous generator using this call:
for await (const button of formElements("button-container-css", "button-css", 6))
{
await clickOn(button);
//other async stuff...
}
But what I want to do is take those specific parameters out of the main function and have a helper function (formButtons()
) provide them instead, which I think should look like this (?):
formButtons = async function*() {
yield await formElements("button-container-css", "button-css", 6);
}
so my main function can be a LITTLE cleaner:
for await (const button of formButtons())
{
await clickOn(button);
//other async stuff...
}
But it literally skips everything once it hits the yield
in formButtons()
, returning null and causing errors. I think the error must either be in my formButtons()
function or else it's some unfortunate artifact of not using the stable release of Node, but I'm hopeful it's something I can fix
Is there an error or a workaround for this?
With the caveat that I've used generators only a few times in toy applications, the situation you've got is basically a delegation from one generator to another one. Since what you want to do is "pass through" control to the sub-generator completely, you can use yield*
instead of yield
. It basically means, "yield everything you can get from this generator". So:
formButtons = async function*() {
yield* await formElements("button-container-css", "button-css", 6);
}