同步嵌套的异步任务

Synchronize nested async task

我有嵌套的异步任务。下面的函数遵循此流程:loadEpisodes(加载剧集列表)-> 使用完成的数组循环遍历每个剧集,并为特定剧集加载评论(另一个异步任务)。

问题是:comletion(fullyEpisodes) 在完成评论加载任务之前执行。我尝试使用 Dispatch Group(第二个代码块),但它不起作用。

func loadComments(comletion: @escaping ([Episode]) -> Void){
loadEpisodes(completion: {
    episodes in
    var fullyEpisodes = [Episode]()
    for episode in episodes {
        WebService().load(resource: episode.comment, comletion: {
            comments in
            if let comments = comments {
                let _episode = Episode(id: episode.id, title: episode.title, comments: comments)
                fullyEpisodes.append(_episode)
                print("done")
            }
        })
    }
    comletion(fullyEpisodes)

})
}

实施调度组:

func loadComments(comletion: @escaping ([Episode]) -> Void){
    loadEpisodes(completion: {
        episodes in
        var fullyEpisodes = [Episode]()
        let group = DispatchGroup()
        for episode in episodes {
            group.enter()
            WebService().load(resource: episode.comment, comletion: {
                comments in
                if let comments = comments {
                    let _episode = Episode(id: episode.id, title: episode.title, comments: comments)
                    fullyEpisodes.append(_episode)
                    print("done")
                }
            })
            group.leave()
        }
        group.wait()
        group.notify(queue: .main, execute: {
            comletion(fullyEpisodes)
        })

    })
}

当我尝试用 "print("something")" (不是新的异步任务)替换评论加载请求时,调度组正在工作。

在您的第二个示例中,(a) 将 group.leave() 移动到 load() 完成处理程序闭包中; (b) 完全删除 group.wait()

func loadComments(comletion: @escaping ([Episode]) -> Void){
    loadEpisodes(completion: {
        episodes in
        var fullyEpisodes = [Episode]()
        let group = DispatchGroup()
        for episode in episodes {
            group.enter()
            WebService().load(resource: episode.comment, comletion: {
                comments in
                if let comments = comments {
                    let _episode = Episode(id: episode.id, title: episode.title, comments: comments)
                    fullyEpisodes.append(_episode)
                    print("done")
                }
                group.leave()
            })
            // group.leave()
        }
        //group.wait()
        group.notify(queue: .main, execute: {
            comletion(fullyEpisodes)
        })

    })
}

或者,使用尾随闭包语法稍微清理一下并修复 completion 拼写:

func loadComments(completion: @escaping ([Episode]) -> Void) {
    loadEpisodes { episodes in
        var fullyEpisodes = [Episode]()
        let group = DispatchGroup()
        for episode in episodes {
            group.enter()
            WebService().load(resource: episode.comment) { comments in
                if let comments = comments {
                    let _episode = Episode(id: episode.id, title: episode.title, comments: comments)
                    fullyEpisodes.append(_episode)
                }
                group.leave()
            }
        }
        group.notify(queue: .main) {
            completion(fullyEpisodes)
        }
    }
}