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 从前端的不同域访问它 - 您要么需要请求不同的工作端点,或将请求从您自己的服务器退回,或类似的东西。