Functions not running in order

戏子无情 提交于 2019-12-13 09:13:02

问题


In viewdidload i have below methods:

var savedSummonerID : Int?
savedSummonerID = LeagueMethodHelper.retrieveSummonerIDFromSummonerName(serverNameAbbreviation, summonerName : summonerName) 
print("haha \(self.savedSummonerID)")

I expect to run methods in order but print statement is actually getting called first.

retrieveSummonerIDFromSummonerName is described below:

static func retrieveSummonerIDFromSummonerName(serverName : String, summonerName : String) -> Int {
    var savedSummonerID = 0
    Alamofire.request(.GET, "https://\(serverName).api.pvp.net/api/lol/\(serverName)/v1.4/summoner/by-name/\(summonerName)?api_key=(key)")
        .responseJSON { response in
            print(response.response?.statusCode) // URL response

            if let JSON = response.result.value {
                if let summonerJSONInfo = JSON[summonerName.lowercaseString] as? [String:AnyObject] {
                    if let summonerID = summonerJSONInfo["id"] as? Int {
                        savedSummonerID = summonerID
                        print(summonerID)
                    }
                    if let SummonerName = summonerJSONInfo["name"] as? String {
                        print(SummonerName)
                    }
                }
            }
    }
    return savedSummonerID
}

I think the solution to run functions in order would be making above function into a closure but I'm not sure how I can do it.


回答1:


You can not return from an asynchronous task.

Your Alamofire task is executed in the background, and you are returning a default value, that is why it looks like it is skipped - but it's just launched in the background and the result is ignored.

The solution is to use a "completion handler" (a callback) instead of a return.

Example:

// (id: Int)->() is the completion handler signature that we add to your method parameters

static func retrieveSummonerIDFromSummonerName(serverName : String, summonerName : String, completion:(id: Int)->()) {
    Alamofire.request(.GET, "https://\(serverName).api.pvp.net/api/lol/\(serverName)/v1.4/summoner/by-name/\(summonerName)?api_key=xxx")
        .responseJSON { response in
            print(response.response?.statusCode) // URL response

            if let JSON = response.result.value {
                if let summonerJSONInfo = JSON[summonerName.lowercaseString] as? [String:AnyObject] {
                    if let summonerID = summonerJSONInfo["id"] as? Int {

                        // use the completion where the result becomes available
                        completion(id: summonerID)

                    }
                    if let SummonerName = summonerJSONInfo["name"] as? String {
                        print(SummonerName)
                    }
                }
            }
    }
}

You call it like that, with a "trailing closure":

LeagueMethodHelper.retrieveSummonerIDFromSummonerName(serverNameAbbreviation, summonerName: summonerName) { (id) in
    savedSummonerID = id
    print(savedSummonerID)
}



回答2:


You are starting an asynchronous task in retrieveSummonerIDFromSummonerName. When it completes this block is executed:

    .responseJSON { response in
        print(response.response?.statusCode) // URL response

        if let JSON = response.result.value {
            if let summonerJSONInfo = JSON[summonerName.lowercaseString] as? [String:AnyObject] {
                if let summonerID = summonerJSONInfo["id"] as? Int {
                    savedSummonerID = summonerID
                    print(summonerID)
                }
                if let SummonerName = summonerJSONInfo["name"] as? String {
                    print(SummonerName)
                }
            }
        }
}

If you want the print statement to execute after, you can include it at the end of this block like this:

    .responseJSON { response in
        print(response.response?.statusCode) // URL response

        if let JSON = response.result.value {
            if let summonerJSONInfo = JSON[summonerName.lowercaseString] as? [String:AnyObject] {
                if let summonerID = summonerJSONInfo["id"] as? Int {
                    savedSummonerID = summonerID
                    print(summonerID)
                }
                if let SummonerName = summonerJSONInfo["name"] as? String {
                    print(SummonerName)
                }
            }
        }
    print("haha \(self.savedSummonerID)")
}

Alternatively, you could implement some sort of callback which you would call at the end of your completion block in the same way.



来源:https://stackoverflow.com/questions/35828921/functions-not-running-in-order

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!