Javascript 如何从AngularJS中的异步树结构API创建承诺 如何等待不确定的递归承诺来解决

Javascript 如何从AngularJS中的异步树结构API创建承诺 如何等待不确定的递归承诺来解决,javascript,angularjs,recursion,promise,Javascript,Angularjs,Recursion,Promise,我的应用程序中的流量控制有问题。我有一个分层(类似于家族?)数据结构,类似于: {name:“Bob”,孩子:[{name:“Tim”,孩子:[..]},{另一个孩子..}]} 这种结构可以是多层次的 现在我要做的是递归地迭代所有人,获取他们的ID,调用api来检索这个人的图片 Psuedo代码: gatherPicture(hierarchy); console.log("I want to wait before doing this!") // Logs too early functi

我的应用程序中的流量控制有问题。我有一个分层(类似于家族?)数据结构,类似于:

{name:“Bob”,孩子:[{name:“Tim”,孩子:[..]},{另一个孩子..}]}

这种结构可以是多层次的

现在我要做的是递归地迭代所有人,获取他们的ID,调用api来检索这个人的图片

Psuedo代码:

gatherPicture(hierarchy);
console.log("I want to wait before doing this!") // Logs too early
function gatherPicture(person) {
    // api request (promise)
    getPicture(person.id).then(r => {
        person.picture = r;
        person.children.forEach(gatherPicture);
    }) 
}
希望代码有意义。如何让代码等待gatherPicture函数处理并解析所有人

如果它增加了什么,我正在使用AngularJS,并且确实可以访问可用的$q promise服务。但是我不明白如何设置这个特殊的承诺链,因为它们是在递归函数中构建的


非常感谢

关键是使用
$q.all
Array.prototype.map

gatherPicture(hierarchy)
.then(() => {
    console.log("I want to wait before doing this!")
})

function gatherPicture(person) {
    // api request (promise)
    return getPicture(person.id).then(r => {
        person.picture = r;
        return  $q.all(person.children.map(gatherPicture));
    }) 
}
因此,首先从您的
gatherPicture
返回从
getPicture
开始的承诺链,这样您就可以建立一个合适的承诺链


接下来,您要使用
person.children.map(gatherPicture)
为所有孩子创建一个承诺列表,然后使用
Promise将其解析。所有

另一种方法可能是首先展平树:

gatherPicture = (person) => {
    getPicture(person.id)
    .then(data => {
        person.picture = data;
        return Promise.all(person.children.map(gatherPicture));
    }) 
}
const flant=(tree)=>(tree.children | |[])
.reduce((展平,子项)=>展平.concat(展平(子项)),[])
.concat(树);
然后,给出一个简单的
gatherPicture
函数:

constgatherpicture=(person)=>getPicture(person.id)。然后((picture)=>{
person.picture=图片;
});
您可以轻松地同时等待它们全部完成:

const gatherPictures=(tree)=>Promise.all(展平(tree.map)(gatherPicture));
使用:

收集图片(层次结构)。然后(()=>{ 控制台日志(“完成”); });
非常感谢您澄清使用.map的重要性。在这种情况下,映射可以正确地链接这些。@summay另一个注意事项,这种方法有一个缺点,它将在“同一时间”开始所有子级的初始下载(JavaScript不是多线程的)但是下载是可以的。@Summy你可能想用AngularJS的版本试试:
$q.all()
这个结构叫做树型:这里的答案使用通用的ES6承诺。请记住,ES6承诺没有与AngularJS框架集成。只有在AngularJS执行上下文中应用的操作才能从AngularJS数据绑定、异常处理、属性监视等中受益。在AngularJS框架中使用
$q.all
。这里的答案使用通用ES6承诺。请记住,ES6承诺没有与AngularJS框架集成。只有在AngularJS执行上下文中应用的操作才能从AngularJS数据绑定、异常处理、属性监视等中受益。在AngularJS框架中使用
$q.all
。这里的答案使用通用ES6承诺。请记住,ES6承诺没有与AngularJS框架集成。只有在AngularJS执行上下文中应用的操作才能从AngularJS数据绑定、异常处理、属性监视等中受益。请在AngularJS框架中使用
$q.all