【问题标题】:Callback/Promise nested loop, 2 API callsCallback/Promise 嵌套循环,2 个 API 调用
【发布时间】:2018-06-14 00:00:40
【问题描述】:

对于我找不到更好的标题,我深表歉意。 如果这个问题已经有了答案,请随时在下面的 cmets 中通知我,我会立即将其删除,但请记住,这不是一般性问题。

说明: 有一个 API 调用将从服务器(一个数组)获取数据,然后基于该数组启动一个循环,在循环内我们有另一个基于父索引的 API(子通过使用父索引进行 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');
});

我想在将每个父级的每个子级推入一个数组之后,在控制台中打印 "yellow"(或获取数组的长度)。


到目前为止我所做的尝试:

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 ...),请告诉我并分享您的想法。

【问题讨论】:

    标签: javascript ecmascript-6 es6-promise


    【解决方案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');
    });
    

    【讨论】:

    • 感谢您的编辑和输入。我还没有检查您的解决方案,但@riv 解决方案对我有用,所以我检查了它作为答案。为您的时间和解决方案 +1
    • 这对 return 语句来说有点矫枉过正,因为只使用了其中一个。
    • @riv 不返回值的函数是无用的。并且至少外部三个 return 语句此代码工作所必需的(我不知道 content.map(…) 循环的作用)
    • 无返回函数什么时候没用了?仅当重新排序代码以将输出置于第一个 then 之外时才需要外部 return(这很好,但不是问题的一部分),并且仅当您想访问 promise.all 的结果时才需要第三个 return ,这里不是这样,因为我们只需要知道它什么时候完成。
    • @riv 如果它没有返回任何东西,它是 procedure 而不是 function :-D 是的,我通常尝试编写好的代码,而不仅仅是“有效”的东西对于一些特定的问题场景。
    【解决方案2】:

    你几乎用第一个Promise.all sn-p 得到它,但它里面的函数没有返回它创建的承诺,所以你在一个未定义的数组上调用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 只是一个循环)。

    【讨论】:

    • 感谢您的输入,让我检查一下
    猜你喜欢
    • 2023-04-04
    • 1970-01-01
    • 2020-09-17
    • 2017-08-08
    • 2016-03-02
    • 1970-01-01
    • 2014-07-09
    • 2017-12-23
    • 1970-01-01
    相关资源
    最近更新 更多