javascript - 如何为嵌套异步调用创建 Promise

标签 javascript asynchronous ecmascript-6 promise es6-promise

我有两个函数正在启动异步加载资源。我怎样才能让他们返回 promise 我可以等到加载完成?

  // #1
  LoadMaps() {
    gFileService.getFile('syn-maps.json').then(
      mapItem => this.synMaps = mapItem
    ).then(
      gFileService.getFile('sense-maps.json').then(
        mapItem => this.senseMaps = mapItem
      )
    );
  }

  // #2
  LoadListAndMetadata() {
    gListService.getList().then(lexList => {
      let promises = [];
      lexList.forEach(lexItem => {
        lexItem.selected = false;
        this.lexList[lexItem.lexId] = lexItem;
        if (lexItem.hasMeta) {
          promises.push(gFileService.getFile(lexItem.metaFile).then(
            metaItem => this.metadata[lexItem.lexId] = metaItem
          ));
        }
      });
      $.when(...promises).then(
        () => $.templates('#lexSelectionTemplate').link('#lexSelection', this)
      );
    });
  }

我想得到一个(或两个)Promise,以便我可以等到两者都完成,即文件已加载并且模板已链接。我只是不知道如何获得它们以便将它们归还。简单地将 return 放在每个函数的第一行前面不会为嵌套任务返回正确的函数。我是否必须在这里更改我的设计才能等待最里面的任务?

最佳答案

Simply putting return in front of the first line of each function will not return the correct one for the nested tasks

实际上会的。您确定将其放在所有四个函数的第一行吗?

LoadMaps() {
  return gFileService.getFile('syn-maps.json').then(
//^^^^^^
    mapItem => this.synMaps = mapItem
  ).then(() => { // <== admittedly, you forgot this entire function
    return gFileService.getFile('sense-maps.json').then(
//  ^^^^^^
      mapItem => this.senseMaps = mapItem
    )
  });
}

LoadListAndMetadata() {
  return gListService.getList().then(lexList => {
//^^^^^^
    let promises = [];
    lexList.forEach(lexItem => {
      lexItem.selected = false;
      this.lexList[lexItem.lexId] = lexItem;
      if (lexItem.hasMeta) {
        promises.push(gFileService.getFile(lexItem.metaFile).then(
          metaItem => this.metadata[lexItem.lexId] = metaItem
        ));
      }
    });
    return Promise.all(promises).then(
//  ^^^^^^
      () => $.templates('#lexSelectionTemplate').link('#lexSelection', this)
    );
  });
}
<小时/>

关于LoadMaps,您可能一直在考虑同时运行两个getFile 调用。您可以再次使用 Promise.all 来做到这一点:

LoadMaps() {
  return Promise.all([
//^^^^^^
    gFileService.getFile('syn-maps.json').then(mapItem =>
      this.synMaps = mapItem
    ),
    gFileService.getFile('sense-maps.json').then(mapItem =>
      this.senseMaps = mapItem
    )
  ]);
}

甚至

LoadMaps() {
  return Promise.all([
    gFileService.getFile('syn-maps.json'),
    gFileService.getFile('sense-maps.json')
  ]).then(results => {
    [this.synMaps, this.senseMaps] = results
  });
}

关于javascript - 如何为嵌套异步调用创建 Promise,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45180037/

相关文章:

javascript - 一行解构数组内的对象?

javascript - 检测 JavaScript 中的 for...of 循环支持

JavaScript - 用数组助手替换 for 循环

javascript - 在 Cucumber 中测试 JQuery UI slider

javascript - 切换类名 onclick JavaScript

javascript - 连接数组前缀和数组反转前缀的最佳方法

Javascript async parallel - 如何返回最终结果/回调?

Javascript:检测文件阅读器中是否有图像

xcode - 将异步获取的数据传递给另一个类

asynchronous - 如何识别异步串行位流中的起始位