等到多个请求被执行并完成阻止

时间:2018-03-14 08:19:01

标签: ios swift alamofire grand-central-dispatch nsurlrequest

考虑一个场景,我有一个功能" REFRESH",这个功能同时通过不同的方法调用,让我们说这些方法是" A",&#34 ; B"," C"。如果方法" A"电话" REFRESH TOKEN"首先是方法" B"和" C"应该等到它完成。

我如何实现这种情况?感谢您的帮助!

let serialQueue = DispatchQueue(label: "serialQueue")
var myFlag = false


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    self.refresh(param: 1) // Method A
    self.refresh(param: 2) // Method B
    self.refresh(param: 3) // Method C

}

// Method REFRESH

func refresh(param: NSInteger) -> Void {

let absolutePath = "MY SAMPLE API"
var headers: [String: String] = Dictionary<String, String>();
headers["Content-Type"] = "application/json"


serialQueue.sync {
    print("\nEntered ", param)
Alamofire.request(absolutePath, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: headers).responseString {
    response in
    switch response.result {
    case .success:
        print("SUCCESS")
        break
    case .failure(let error):
        print(error)
    }

}

以上代码输出:

Entered  1
Entered  2
Entered  3
SUCCESS
SUCCESS
SUCCESS

我需要这样的输出:

Entered  1
SUCCESS
Entered  2
SUCCESS
Entered  3
SUCCESS

4 个答案:

答案 0 :(得分:1)

var formData = new FormData()
        var politician_id = this.props.image_reducer.politicianList[this.props.image_reducer.selectedPoliticianRow].person.id

        console.log("id is "+ politician_id)
        var politician =  {
            "description": document.getElementById('description-input').value,
            "political_party": document.getElementById('party-input').value,
            "constituency": document.getElementById('constituency-input').value,
            "positions": document.getElementById('positions-input').value,
        }
        formData.append("name", document.getElementById('name-input').value)
        formData.append("dob", document.getElementById('birth-input').value)
        formData.append("born_location",document.getElementById("birth-location-input").value)
        formData.append("current_location",document.getElementById('current-location-input').value)
        formData.append("description", document.getElementById('description-input').value)
        formData.append("father_name", document.getElementById('father-input').value)
        formData.append("mother_name", document.getElementById('mother-input').value)
        formData.append("partner_name", document.getElementById('name-input').value)
        formData.append("religion", document.getElementById('religion-input').value)
        formData.append("caste", document.getElementById('caste-input').value)
        formData.append("occupation", "politician")
        formData.append("education", document.getElementById('occupation-input').value)
        formData.append("politician", JSON.stringify(politician))

答案 1 :(得分:0)

这样的东西?

var param:[Int] = [1,2,3]

func refresh(){ 

    DispatchQueue.global().async {

        for i in 0..<param.count{

            let group = DispatchGroup()
            group.enter()
            print("\nEntered ", param[i])

            let absolutePath = "MY SAMPLE API"
            var headers: [String: String] = Dictionary<String, String>();
            headers["Content-Type"] = "application/json"

            Alamofire.request(absolutePath, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: headers).responseString {
    response in
                switch response.result {
                    case .success:
                        print("SUCCESS")
                        break
                    case .failure(let error):
                        print(error)
                }

                group.leave()

            }

            group.wait()

        }
    }
}

答案 2 :(得分:0)

根据您的要求,我想说您希望对refresh次来电进行序列化调用。这意味着您必须等到一个呼叫结束才能呼叫下一个。

简单,但有点难看的解决方案是使用完成闭包:

override func viewDidLoad() {
    super.viewDidLoad()
    self.refresh(param: 1, completion: { [weak self] in
        self?.refresh(param: 2, completion: { [weak self] in
            self?.refresh(param: 3, completion: nil)
        })
    })
}

// Method REFRESH

func refresh(param: NSInteger, completion: (() -> Void)?) -> Void {

    let absolutePath = "MY SAMPLE API"
    var headers: [String: String] = Dictionary<String, String>();
    headers["Content-Type"] = "application/json"

    print("\nEntered ", param)
    Alamofire.request(absolutePath, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: headers).responseString {
        response in
        switch response.result {
        case .success:
            print("SUCCESS")
            break
        case .failure(let error):
            print(error)
        }
        completion?()
    }
}

根据您在评论中所说的内容(您只想在第一次调用中获取刷新令牌然后无关紧要),您可以将其重写为viewDidLoad

self.refresh(param: 1, completion: { [weak self] in
    // these two can now go in parallel, since the first call got you the refresh token
    self?.refresh(param: 2, completion: nil)
    self?.refresh(param: 3, completion: nil)
})

答案 3 :(得分:0)

您需要的是名为 资源锁定 的内容。您可以使用DispatchGroup

来实现此目的

首先,您需要创建DispatchGroup。在控制器中添加属性:

let dispatchGroup = DispatchGroup()

然后将refresh(param:)函数修改为:(我修改了一些编码模式)

func refresh(param: NSInteger) -> Void {
    // You lock your resource by entering to the dispatch group
    dispatchGroup.enter()
    let absolutePath = "MY SAMPLE API"
    var headers = [String: String]()
    headers["Content-Type"] = "application/json"
    print("Entered \(param)")
    Alamofire.request(absolutePath, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: headers).responseString { [weak self] (response) in
        switch response.result {
        case .success:
            print("SUCCESS \(param)")
            break
        case .failure(let error):
            print(error)
        }
        // You release the resource as soon as you get the response so that other processes may be able to use the resource
        self?.dispatchGroup.leave()
    }
    // The lock continues by invoking the wait method
    dispatchGroup.wait()
}

所以,这将起作用:

Method 1&amp; Method 2正在请求使用相同的资源。执行Method 1时,Method 2将等待方法1完成。 Method 1完成后,Method 2将有机会开始执行。

因此,基本上哪个方法首先开始执行将完成,然后另一个将启动 。虽然不能保证首先开始执行(因为,你不需要彼此依赖)。但它取决于您调用此方法的顺序。