Reputation: 6693
I want to return a generator for the cars being created. The issue is, I nest an API to receive some random colours for the cars upon which I cannot yield
to since they're not declared as generator functions.
I tried to create the reference using let car
but because the request is async
, it yields before the car is instanced. Perhaps I need to pass this as reference? Any ideas?
static async api()
{
return (await fetch('http://www.colr.org/json/colors/random/8')).json();
}
static* createCars(n)
{
for(let i = 1; i <= n; i++) {
Car.api().then(resp => {
let car = (new self({
x: 0,
y: 250,
colour: "#" + resp.colors[3].hex,
windowsColour: "#" + resp.colors[2].hex,
number: i
})).draw();
});
yield car;
}
}
Uncaught ReferenceError: car is not defined
Upvotes: 0
Views: 82
Reputation: 371233
Use an async generator instead, so that you can await
in the main body of the generator function. This allows you to retrieve the asynchronous value at the top level of the function, so you can yield it. (You can't yield inside callbacks, after all.)
class Car {
static async api() {
return (await fetch('http://www.colr.org/json/colors/random/8')).json();
}
static async * createCars(n) {
for (let i = 1; i <= n; i++) {
const resp = await Car.api();
/*
let car = (new self({
x: 0,
y: 250,
colour: "#" + resp.colors[3].hex,
windowsColour: "#" + resp.colors[2].hex,
number: i
})).draw();
yield car;
*/
yield "#" + resp.colors[3].hex;
}
}
}
(async () => {
for await (const color of Car.createCars(1)) {
console.log(color);
}
})();
Note that colr.org
has standard CORS protections, so you can't fetch
to it from a different domain on the front-end - you'll either need to request a different working endpoint, or bounce the request off your own server, or something like that.
Upvotes: 3
Reputation: 83597
One solution is to do
const resp = await Care.api();
const car = (new self({
x: 0,
y: 250,
colour: "#" + resp.colors[3].hex,
windowsColour: "#" + resp.colors[2].hex,
number: i
})).draw();
yield car;
This should at least get you closer to something that actually works.
The disadvantage is that it blocks for each request rather than letting each one resolve asynchronously. I still think it's a good place to start to at least see if your code works the way you want. Then follow up with some modifications to correctly take advantage of async API calls. (I don't know the exact solution for that next step off the top of my head, though.)
Upvotes: 1