首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用异步代码在forEach循环上进行允诺/回调

问如何使用异步代码在forEach循环上进行允诺/回调
EN

Stack Overflow用户
提问于 2015-09-29 15:21:04
回答 3查看 1.5K关注 0票数 1

我想我是在寻找希望,但我不知道如何在我的情况下使用它。

只有当我的异步代码全部完成时,我才想使用console.log('ended')。

我有一个针对DZ.api的回调,但没有针对forEach()的回调,这样做最好的方法是什么?

代码语言:javascript
复制
    _.forEach(filteredTracks, function(n) {
        DZ.api('/playlist/'+ n.id +'/tracks', function(response) {
            _.forEach(response.data, function(n) {
                SP.api('/search/'+n.title, function(response) {
                    console.log(response);
                });
            });
        });
    });
    console.log('ended');
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-09-29 15:37:02

你在找Promise.all -> Promise.all(arrayOfPromise).then(function (result) {})

对于当前的代码,如果SP.api已经承诺兼容,只需:

代码语言:javascript
复制
_.map(filteredTracks, function(n) {
    return DZ.api('/playlist/'+ n.id +'/tracks')
            .then(function (response) {
                _.map(response.data, function(n) {
                    return SP.api('/search/'+n.title);
                });

                return Promises.all(response.data);
            });
    });
});

Promise.all(filteredTracks)
    .then(function (results) {
        console.log('ended');
    });

如果SP.api和DZ不返回承诺,您可以:

普罗米西 SP.api DZ Api和使用我之前编写的相同代码

或者在._map中返回承诺

代码语言:javascript
复制
_.map(filteredTracks, function(n) {
    var promise = new Promise(function (resolve, reject) {
        DZ.api('/playlist/'+ n.id +'/tracks', function (response) {
                _.map(response.data, function(n) {
                    var insidePromise = new Promise(function (resolve, reject) {
                        return SP.api('/search/'+n.title, function (result) {
                            resolve(result);
                        });
                    })

                    return insidePromise;
                });

                resolve(Promises.all(response.data));
            });
        });
    });

    return promise;
});

Promise.all(filteredTracks).then(function (results) {
        console.log('ended');
    });
票数 4
EN

Stack Overflow用户

发布于 2015-09-29 15:35:41

您想要的是将forEach替换为map,并让每个调用返回一个承诺,连接内循环的结果,因为您有两个级别。然后,将承诺数组传递给Promise.all(),这将创建一个承诺,当数组中的所有承诺都已解析时,该承诺就会得到解决。要做到这一点,您必须重构代码以返回来自DZ.api函数的承诺,而不是使用回调。简言之:

代码语言:javascript
复制
let promises = filteredTracks.map(track => {
    return DZ.promisedApi(track).then(response => {
        return Promise.all(response.data.map(n => SP.promisedApi(n))
    }) 
})

Promise.all(promises).then(() => console.log("done!"))
票数 2
EN

Stack Overflow用户

发布于 2015-09-29 15:41:39

您没有指定所使用的库,但总的来说,我建议您将所有API调用的承诺保存到一个数组中,然后使用Promises.all()

因此,您将得到类似的内容(警告:未经测试的代码,仅供参考):

代码语言:javascript
复制
var promisesArray = []

_.forEach(filteredTracks, function(n) {
    DZ.api('/playlist/'+ n.id +'/tracks', function(response) {
        _.forEach(response.data, function(n) {
            promisesArray.push( SP.api('/search/'+n.title, function(response) {
                console.log(response);
            }));
        });
    });
});

Promise.all(promisesArray)
        .then(function(value){
          console.log('ended');
        })

基本上,正如在承诺参考页上所述,Promise.all创建了一个新的承诺,当所有作为参数传递的承诺都被解析时,这个承诺就会得到解决。在我看来符合你的用例。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32847857

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档