如何在Swift中依次执行大量网络调用?

时间:2018-10-22 09:55:34

标签: swift multithreading alamofire

例如,我有一组URL以获取json数据。列表数量可以达到数千。没关系,然后我有一个循环从每个元素中检索json数据。

let urls : [URL] = getUrls();
var results = [String: Dictionary]();

for url in url {
    networkRequest (url: url, callback: { json in
        results[url.absoluteString] = json;
    });
}

问题在于所有这些请求都是同时进行的,因此结果要么运行很慢,要么部分丢失。

所以我认为那是因为请求同时运行太多。因此,我想添加某种网络呼叫配额以运行。

let urls : [URL] = getUrls();
var results = [String: Dictionary]();
var quota = 0;

for url in url {
    quota += 1;
    while quota > 5 { }
    networkRequest (url: url, callback: { json in
        quota -= 1;
        results[url.absoluteString] = json;
    });
}

使用打印的控制台消息,我可以看到前5个网络调用转到了networkRequest函数,但是从来没有任何返回的数据。回调从未被回调。我应该如何实施此配额调用?

1 个答案:

答案 0 :(得分:2)

您可以尝试创建串行队列

let que = DispatchQueue(label: "custQ") 
for url in urls {
  que.sync {
    quota += 1;
    while quota > 5 { }
    networkRequest (url: url, callback: { json in
        quota -= 1
        results[url.absoluteString] = json
    })
    }

}

但请注意,networkRequest应该在相同的队列线程中运行,请不要分派它,或递归调用它

var counter = 0
func callUrl(_ url:URL) {
    quota += 1;
    while quota > 5 { }
    networkRequest (url: url, callback: { json in
        self.quota -= 1
        self.results[url.absoluteString] = json
        self.counter +=1
        if self.counter < 20 {  /// or set any number 
          self.callUrl(urls[counter])
        }
    })

}