例如,我有一组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函数,但是从来没有任何返回的数据。回调从未被回调。我应该如何实施此配额调用?
答案 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])
}
})
}