簡體   English   中英

如何為嵌套的異步調用創建Promise

[英]How to create a Promise for nested async calls

我有兩個函數正在開始異步加載資源。 我該如何讓他們退回保證可以等到加載完成的承諾?

  // #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放在每個函數的第一行前面將不會為嵌套任務返回正確的函數。 我是否必須在這里更改設計才能等待最內在的任務?

僅僅將return放在每個函數的第一行的前面將不會為嵌套任務返回正確的函數

實際上會。 您確定將它放在所有四個功能的第一行嗎?

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
  });
}

如果您只需要知道最后一個呼叫何時完成,則可以使用以下框架:

  function firstCall() { return new Promise((y,n) => setTimeout( () => y('firstCall'), 500 )); } function secondCall() { return new Promise((y,n) => setTimeout( () => y('secondCall'), 800 )); } function promiseTest() { Promise.all([ firstCall(), secondCall() ]).then( function(data) { console.log( data ); }) .catch( function(err) { console.log( 'Error executing promisses.', err ); }); } promiseTest(); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM