在我的应用中,我需要调用getGroup()
函数,该功能使用用户信息与我们的CMS联系,并根据当前在CMS中的信息和内容将它们放在一个组中。此组信息包含在我们其他API调用的URL中。
问题是,当应用程序启动并且用户组尚未缓存时,这些API呼叫触发getGroup中的每一个都可以实际进行API调用,而不仅仅是获得缓存的组。我想减少它,以便呼叫仅一次,而其他呼叫的呼叫等待直到听到响应。
伪代码示例我想做什么:
var isGettingGroup = false
func getGroup(completion: (group?, error?)) {
if isGettingGroup {
wait for notification
}
if let group = groupFromCache() {
completion(group, nil)
} else {
isGettingGroup = true
callGetGroupAPI() { group, error in
completion(group, error)
cacheGroup(group)
isGettingGroup = false
send notification to continue
}
}
}
我已经尝试使用信号量,但是我认为我需要更全局的东西,例如NotificationCenter
的帖子。我的主要问题是根据通知而不是等待分配的时间暂停单个功能调用。我已经多次使用DispatchGroups
,但这似乎是相反的问题 - 多个功能在一个呼叫上等待,而不是在函数/块上等待多个函数。
预先感谢
呼叫只有一次,而其他呼叫的呼叫等待等到听到响应
该函数应同步在串行背景队列上运行代码。这使得它不可能通过两个不同的线程同时称为。这是您的伪代码的伪代码;未经测试,但它显示了我相信可以起作用的东西:
let q = DispatchQueue()
func getGroup(completion: (group?, error?)) {
q.sync { // lock out any other calls to getGroup until we finish
let g = DispatchGroup()
g.enter()
if let group = groupFromCache() {
completion(group, nil)
g.leave()
} else {
callGetGroupAPI() { group, error in
completion(group, error)
cacheGroup(group)
g.leave()
}
}
g.notify()
}
}
我不完全确定需要调度组,但我将其放入将所有内容保持在sync
的范围内。
edit OP表示实际上需要调度组,您需要说g.wait()
而不是notify()
,但否则这有效。