观察异步请求

Observing Asynchronous Requests

我对 API 进行了三个单独的调用。当所有三个调用都完成后,我将聚合数据并使用它来形成一个单独的模型对象。

我想我会使用 属性 观察者来完成这个,但我不知道它是如何实现的。任何帮助或指导将不胜感激。

我创建了一个模型对象,用于进行将响应数据传递到转义闭包中的网络调用。这是解析数据的函数:

func loadLibrary() {

    //  League Data Containers

    var names = Dictionary<Int, String>() // API Call 1
    var titles = Dictionary<Int, String>() // Call 1
    var masteryLevels = Dictionary<Int, Int>() // 2
    var masteryPoints = Dictionary<Int, Int>() // 2

    //  Champion Data Containers

    var championRolesLibrary = Array<Dictionary<String,Array<Role>>>() // 3
    var championWithRoles = Dictionary<String,Array<Role>>() // 3
    var championRoles = Array<Role>() // 3

    //  Making Calls to the APIs

    leagueAPI.downloadStaticData { data in
        //  API Call is made and data is parsed into containers
    }

    leagueAPI.downloadChampionMasteryData { data in
        //  API Call is made and data is parsed into containers
    }

    championAPI.downloadChampionRolesData { data in
        //  API Call is made and data is parsed into containers
    }

    // Once all three calls have completed and the data has been parsed into different containers, the data is all brought together to create a library of objects.

    func aggregateData() {

        //  Take data from all the containers and use them in here.
        //  The issue is when to call this function.

    }
}

解决这个问题的一个简单方法是嵌套所有三个请求:

func loadLibrary() {

    //  League Data Containers

    var names = Dictionary<Int, String>() // API Call 1
    var titles = Dictionary<Int, String>() // Call 1
    var masteryLevels = Dictionary<Int, Int>() // 2
    var masteryPoints = Dictionary<Int, Int>() // 2

    //  Champion Data Containers

    var championRolesLibrary = Array<Dictionary<String,Array<Role>>>() // 3
    var championWithRoles = Dictionary<String,Array<Role>>() // 3
    var championRoles = Array<Role>() // 3

    //  Making Calls to the APIs

    leagueAPI.downloadStaticData { data in
        //  API Call is made and data is parsed into containers

        leagueAPI.downloadChampionMasteryData { data2 in

            //  API Call is made and data is parsed into containers
            championAPI.downloadChampionRolesData { data3 in

                //  API Call is made and data is parsed into containers// Once all three calls have completed and the data has been parsed into different containers, the data is all brought together to create a library of objects.

                aggregateData() {

                //  Take data from all the containers and use them in here.
                //  The issue is when to call this function.

                }
            }
        }
    }

}

编辑:您也可以按照@rmaddy 的说法使用 DispatchGroup 来完成您想要的,在这种情况下您可以这样做:

func loadLibrary() {

    //  League Data Containers

    var names = Dictionary<Int, String>() // API Call 1
    var titles = Dictionary<Int, String>() // Call 1
    var masteryLevels = Dictionary<Int, Int>() // 2
    var masteryPoints = Dictionary<Int, Int>() // 2

    //  Champion Data Containers

    var championRolesLibrary = Array<Dictionary<String,Array<Role>>>() // 3
    var championWithRoles = Dictionary<String,Array<Role>>() // 3
    var championRoles = Array<Role>() // 3

    // Create DispatchGroup
    let dispatchGroup = DispatchGroup()

    //  Making Calls to the APIs

    dispatchGroup.enter()
    leagueAPI.downloadStaticData { data in
        //  API Call is made and data is parsed into containers
        dispatchGroup.leave()
    }

    dispatchGroup.enter()
    leagueAPI.downloadChampionMasteryData { data in
        //  API Call is made and data is parsed into containers
        dispatchGroup.leave()
    }
    dispatchGroup.enter()
    championAPI.downloadChampionRolesData { data in
        //  API Call is made and data is parsed into containers
        dispatchGroup.leave()
    }

    // Once all three calls have completed and the data has been parsed into different containers, the data is all brought together to create a library of objects.
    dispatchGroup.notify(queue: DispatchQueue.global(qos: .background)){
        aggregateData() {

            //  Take data from all the containers and use them in here.
            //  The issue is when to call this function.

        }
    }

}