【问题标题】:Observing Asynchronous Requests观察异步请求
【发布时间】:2017-09-27 03:10:01
【问题描述】:

我对 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.

    }
}

【问题讨论】:

  • 到目前为止您尝试过什么?您现有的异步函数是什么样的?
  • @creeperspeak 我已经编辑了我的问题
  • 查看 DispatchGroup 作为当前所选答案的嵌套方法的另一个选项。

标签: ios swift asynchronous callback observer-pattern


【解决方案1】:

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

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.

        }
    }

}

【讨论】:

  • 很好的答案。不过有一件事。您的意思是让 func aggregateData 成为 DispatchGroup 通知闭包的本地函数吗?我猜你的意思是 CALL 函数而不是声明它。
  • @DuncanC 你说得对,我刚刚从问题中复制和粘贴,我错过了,但现在我编辑了我的答案。谢谢!
猜你喜欢
  • 1970-01-01
  • 2018-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-13
  • 1970-01-01
  • 2019-01-11
相关资源
最近更新 更多