1

我有以下按预期工作的功能:

  createObjectFrom(record) {
    let obj = {};

    this.opts.transformers.forEach((transformer, index) => {
      const headerIndex = findIndex(this.headers, (header) => {
        return header === transformer.column;
      });

      const value = transformer.formatter(record[headerIndex]);

      obj[transformer.field] = value;
    });

    return obj;
  }

我想重构它以使用 async await 并在 forEach 的主体中调用一个异步函数,如下所示:

  createObjectFrom(record) {
    let obj = {};

    this.opts.transformers.forEach(async (transformer, index) => {
      const headerIndex = findIndex(this.headers, (header) => {
        return header === transformer.column;
      });

      const result = await this.knex('managers').select('name')

      console.log(result);

      const value = transformer.formatter(record[headerIndex]);

      obj[transformer.field] = value;
    });

    return obj;
  }

这显然会破坏函数,因为 forEach 现在正在异步执行,函数只会执行并离开。

有没有办法可以使用异步等待 forEach 以同步方式执行。我可以重构生成器吗?

4

1 回答 1

1

您不能强制使用普通的 JS 函数来等待异步行为。不可能!

所以你也必须重构你createObjectFrom的异步。然后可能会选择 map/reduce 而不是 forEach。为了表现出色,您不想这样做:

for(transformer of this.opts.transformers) {
    await this.knex('managers').select('name');
}

相反,您应该使用await Promise.all(...).

但是,在您的情况下,对 knex 的调用似乎不依赖于变压器,因此您可以这样做:

async createObjectFrom(record) {
  let obj = {};

  const result = await this.knex('managers').select('name')

  this.opts.transformers.forEach(async (transformer, index) => {
    const headerIndex = findIndex(this.headers, (header) => {
      return header === transformer.column;
    });

    console.log(result);

    const value = transformer.formatter(record[headerIndex]);

    obj[transformer.field] = value;
  });

  return obj;
}

但是,如果您想为每个项目执行诸如 fetch 之类的异步操作,请执行以下操作:

async foo(data) {
  const subDataArr = await Promise.all(data.map(record => loadSubData(record)));

  return subDataArr;
}
于 2016-09-03T22:12:43.050 回答