async / await与`forEach`相关的竞争条件?

时间:2017-03-24 00:05:18

标签: javascript meteor ecmascript-6 promise async-await

我有以下异步功能:

async function createDemoContent({ orgId, userId }) {
  const createTag = promisifyMethod(_createTag);
  const tags = {};

  /* ... */
  [
    'marketing',
    'insights',
    'customer-centric',
    'email marketing',
    'click through rate',
    'tests',
    'research',
    'UX'
  ].forEach(async (label) => {
    const tag = await createTag({
      demo: true,
      label,
      orgId,
    });

    tags[label] = tag._id;
  });

  console.log('all tags:', JSON.stringify(tags));

以防万一有人想看到promisifyMethod(它将Meteor方法转换为有希望的函数调用):

export function promisifyMethod(method: Object) {
  return (...args: Array<any>) => {
    return new Promise((resolve: Function, reject: Function) => {
      method.call(...args, (error: Object, result: any) => {
        if (!error) resolve(result);
        else reject(error);
      });
    });
  }
}

由于某种原因,tags对象显示为空对象。即使第一个属性添加到async对象之前,await / console.log使用tags也一定有问题。但是我在这个await之上有几个forEach个调用,这些似乎工作正常。

这是createTag的代码:

export const createTag = new ValidatedMethod({
  name: 'createTag',

  validate: new SimpleSchema({
    demo: { type: Boolean, optional: true },
    label: String,
    orgId: String,
  }).validator(),

  run(args) {
    const tag = new Tag(args);

    tag.save();
    return tag;
  },
});

1 个答案:

答案 0 :(得分:2)

这是因为您正在调用异步回调函数,但并未等待它完成。 forEach仅执行该函数,但不等待异步回调返回的承诺解析。

你可以这样做:

for (const label of labels) {
    const tag = await createTag(args)

    tags[label] = tag._id
}
相关问题