当前位置:  开发笔记 > 编程语言 > 正文

异步/等待不等待

如何解决《异步/等待不等待》经验,为你挑选了1个好方法。



1> Michelle Til..:

我相信这个问题在你的forEach电话中_scan.供参考,请参阅使用ES7驯服异步野兽的这篇文章:

但是,如果您尝试使用异步函数,那么您将得到一个更微妙的错误:

let docs = [{}, {}, {}];

// WARNING: this won't work
docs.forEach(async function (doc, i) {
  await db.post(doc);
  console.log(i);
});
console.log('main loop done');

这将编译,但问题是这将打印出来:

main loop done
0
1
2

发生的事情是主要功能是提前退出,因为await它实际上是在子功能中.此外,这将同时执行每个承诺,这不是我们的意图.

经验教训是:在异步函数中有任何函数时要小心.将await只会暂停其父功能,因此检查它在做什么,你真的觉得它在做什么.

所以forEach调用的每次迭代都是并发运行的; 他们不是一次执行一个.只要匹配条件的条件i === keys.length - 1完成_scan,即使其他异步函数forEach仍然在执行,也会解析并返回promise .

你需要更改forEach为a map来返回一个promises数组,你可以await*从中返回_scan(如果你想同时执行它们然后在它们全部完成后调用它们),或者在一个a-a执行它们-time如果您希望它们按顺序执行.


作为旁注,如果我正确读取它们,可以简化一些异步功能; 请记住,当await一个async函数调用返回一个值时,只需调用它就会返回另一个promise,并且从async函数返回一个值与返回一个在非async函数中解析为该值的promise相同.所以,例如,_get可以是:

async _get(type, id) {
  var data = _json[id] = _json[id] || await this._api(type, id);

  console.log(data)

  if (isAsset(data)) {
    return data;
  } else if (isEntry(data)) {
    await this._scan(data);
    return data;
  } else {
    const error = 'Response is not entry/asset.';
    console.log(error);
    throw error;
  }
}

同样,_scan可能是(假设您希望forEach并发执行主体):

async _scan(data) {
  if (data && data.fields) {
    const keys = Object.keys(data.fields);

    const promises = keys.map(async (key, i) => {
      var val = data.fields[key];

      if (isLink(val)) {
        var child = await this._get(val.sys.linkType.toUpperCase(), val.sys.id);

        this._inject(data.fields, key, undefined, child);
      } else if (isLinkArray(val)) {
        var children = await* val.map(async (link) => await this._get(link.sys.linkType.toUpperCase(), link.sys.id));

        children.forEach((child, index) => {
          this._inject(data.fields, key, index, child);
        });
      } else {
        await new Promise((resolve) => setTimeout(resolve, 0));
      }
    });

    await* promises;
  } else {
    const error = 'Required data is unavailable.';
    console.log(error);
    throw error;
  }
}

推荐阅读
低调pasta_730
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有