2017-07-19 59 views
0

我有两个函数开始异步加载资源。我怎样才能让他们回到承诺,我可以等待加载完成?如何为嵌套的异步调用创建承诺

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

我想获得一个承诺(或两个),这样我可以等到双方完成后,即文件被加载和模板链接。我只是不明白我能如何获得它们以便它们能够被返回。简单地将return放在每个函数的第一行之前将不会为嵌套任务返回正确的一个。我是否必须在这里改变我的设计才能够等待最内在的任务?

+1

唉!你为什么使用'$ .when'而不是'Promise.all' –

+0

我刚刚学习ES6,谢谢你的建议。 –

+1

确实[此代码](https://jsfiddle.net/qombct3f/)解决您的问题?我不太确定你要诚实的承诺 –

回答

1

干脆把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 
    }); 
} 
+0

OP可以通过取消第二次返回来避免第二次返回。 – danh

+0

@danh他可以避免嵌套,但不是回报 – Bergi

+0

啊,好吧,我只想到外面的'return's。如果内部函数也返回promise,那么外部函数会自动等待它们? –

1

如果你需要的是知道什么时候最后一次通话已经完成,你可以简单地使用这个骨架:

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