JavaScript 中的生成器由于包含在异步请求中而无法正常工作
Generator in JavaScript not working due to being wrapped in an async request
我想 return 为正在创建的汽车生成一个发电机。问题是,我嵌套了一个 API 来为我无法 yield
的汽车接收一些随机颜色,因为它们没有被声明为生成器函数。
我尝试使用 let car
创建引用,但因为请求是 async
,它在汽车实例化之前就让步了。也许我需要将其作为参考传递?有什么想法吗?
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
一个解决方案是
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;
这至少应该让您更接近实际可行的东西。
缺点是它会阻塞每个请求,而不是让每个请求异步解析。我仍然认为这是一个开始的好地方,至少可以看看您的代码是否按您想要的方式工作。然后进行一些修改以正确利用异步 API 调用。 (不过,我不知道下一步的确切解决方案。)
改用异步生成器,这样您就可以在生成器函数的主体中await
。这允许您在函数 的顶层检索异步值 ,因此您可以 yield 它。 (毕竟你不能让出内部回调。)
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);
}
})();
请注意,colr.org
具有标准的 CORS 保护,因此您不能 fetch
从前端的不同域访问它 - 您要么需要请求不同的工作端点,或将请求从您自己的服务器退回,或类似的东西。
我想 return 为正在创建的汽车生成一个发电机。问题是,我嵌套了一个 API 来为我无法 yield
的汽车接收一些随机颜色,因为它们没有被声明为生成器函数。
我尝试使用 let car
创建引用,但因为请求是 async
,它在汽车实例化之前就让步了。也许我需要将其作为参考传递?有什么想法吗?
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
一个解决方案是
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;
这至少应该让您更接近实际可行的东西。
缺点是它会阻塞每个请求,而不是让每个请求异步解析。我仍然认为这是一个开始的好地方,至少可以看看您的代码是否按您想要的方式工作。然后进行一些修改以正确利用异步 API 调用。 (不过,我不知道下一步的确切解决方案。)
改用异步生成器,这样您就可以在生成器函数的主体中await
。这允许您在函数 的顶层检索异步值 ,因此您可以 yield 它。 (毕竟你不能让出内部回调。)
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);
}
})();
请注意,colr.org
具有标准的 CORS 保护,因此您不能 fetch
从前端的不同域访问它 - 您要么需要请求不同的工作端点,或将请求从您自己的服务器退回,或类似的东西。