回调/承诺嵌套循环,2个API调用

时间:2018-06-13 15:51:25

标签: javascript ecmascript-6 es6-promise

我对标题的道歉我无法找到更好的东西。 如果这个问题有答案已经随时在下面的评论中通知我并立即将其删除但请记住这不是一般性问题。

解释: 有一个API调用将从服务器(一个数组)获取数据,然后基于该数组它将启动一个循环,在循环内我们有另一个基于父索引的API(通过使用父索引的子make API调用)和获取一些数据并将它们映射到变量(数组)。我需要在最后一位父母的最后一个孩子完成工作后调用回调。

模仿代码

for(let i=0;i<2;++i){
    for(let j=0;j<2;++j){
        map data into another array with predefined shape
        console.log(i +", "+ j)
    }
}
console.log('good to go for callback');

理想的结果

0, 0
0, 1
1, 0
1, 1
good to go for callback

真实代码:

var projects = api.getProjects(req);

projects.then(function(response){
    response.projects.map(_e => {
        var project = api.getProjectContent(_e.id);
        project.then(function(_response){
            _response.content.map(e=> {
                a_globa_array.push(...);
                console.log('hello');
            });
        });
    });

    console.log('yellow');
});

我想完全将每个单亲中的每个孩子推入一个数组后,在控制台中打印&#34;黄色&#34; (或获取数组的长度)。< / p>

到目前为止我尝试过的事情:

var projects = api.getProjects(req);

projects.then(function(response){
    Promise.all(response.projects.map(_e => {
        var project = api.getProjectContent(_e.id);
        project.then(function(_response){
            _response.content.map(e=> {
                a_globa_array.push(...);
                console.log('hello');
            });
        });
    })).then(()=>{ console.log('yellow'); });
});

var projects = api.getProjects(req);

projects.then(function(response){
    let pr = new Promise((resolve, reject) => {response.projects.map(_e => {
        var project = api.getProjectContent(_e.id);
        project.then(function(_response){
            _response.content.map(e=> {
                a_globa_array.push(...);
                console.log('hello');
            });
        });
    })) });

    pr.then(()=>{ console.log('yellow'); });
});

还有一些。以上代码中的错误并不重要,因为我在SO编辑器中编写它们,所以也许我错过了一些括号/花括号。其他信息:没有错误。如果你认为有更好的解决方案而不是承诺(async / await ......),请告诉我并分享你的想法。

2 个答案:

答案 0 :(得分:1)

你的第一次尝试并不是那么遥远。您只需要忘记return来自回调的承诺,例如thenPromise.all可以等待他们:

projects.then(function(response){
    return Promise.all(response.projects.map(_e => {
//  ^^^^^^
        var project = api.getProjectContent(_e.id);
        return project.then(function(_response) {
//      ^^^^^^
            return _response.content.map(e=> {
//          ^^^^^^
                console.log('hello');
                return ...;
//              ^^^^^^
            });
        });
    }));
}).then(array_of_arrays => {
//      ^^^^^^^^^^^^^^^ you get the results here
    // you can un-nest this then() call
    console.log('yellow');
});

答案 1 :(得分:0)

你几乎得到了第一个Promise.all代码段,但它内部的函数没有返回它创建的promise,所以你在未定义的数组上调用Promise.all

试试这个(同样的事情,加上return):

var projects = api.getProjects(req);

projects.then(function(response){
    Promise.all(response.projects.map(_e => {
        var project = api.getProjectContent(_e.id);
        return project.then(function(_response){
            _response.content.map(e=> {
                a_globa_array.push(...);
                console.log('hello');
            });
        });
    })).then(()=>{ console.log('yellow'); });
});

此外,如果您实际上没有返回任何值,我建议您避免使用Array.map。使用forEach代替使意图更清晰(map用于创建新数组,而forEach只是一个循环)。