Reputation: 1391
I have a function. It runs great but when I want to call it again it knows that that function has already been completed before so if I try to call it again it will automatically pass to completed. How do I reset the completion handler?
Code:
func Test(completionHandler: @escaping (_ finished: String?) -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + 10.0) {
completionHandler("finished") // tell the caller that this has completed
}
}
I call it like this:
self.Test(completionHandler: { finished in
print("We have completed function)")
})
If I were to call it again after about a minute. Instead of it waiting 10 seconds like its supposed. It will automatically printed line.
print("We have completed function)")
Things to know:
The code above is a test example me real code is this.
func GoToPage(completionHandler: @escaping (_ finished: String?) -> Void) {
self.webView.evaluateJavaScript("document.getElementById('results').getElementsByClassName('page')[0].getElementsByClassName('name')[0].innerText"){ (value, error) in
if error != nil {
} else {
print(value)
completionHandler("finished")
}
}
}
I call it like this:
self.GoToPage(completionHandler: { finished in
print("We have completed function)")
})
Then I wait one 1-2 minutes and call it again like this the same way.
DispatchQueue.main.asyncAfter(deadline: .now() + 130.0) {
self.GoToPage(completionHandler: { finished in
print("We have completed function")
})
}
An it prints me the line We have completed function right off the bat when called.
EXAMPLE:
This puts it all together
self.GoToPage(completionHandler: { finished in
print("We have completed function)")
NextStep()
})
func NextStep(){
DispatchQueue.main.asyncAfter(deadline: .now() + 130.0) {
self.GoToPage(completionHandler: { finished in
print("We have completed function")
})
}
}
func GoToPage(completionHandler: @escaping (_ finished: String?) -> Void) {
self.webView.evaluateJavaScript("document.getElementById('results').getElementsByClassName('page')[0].getElementsByClassName('name')[0].innerText"){ (value, error) in
if error != nil {
} else {
print(value)
completionHandler("finished")
}
}
}
Upvotes: 0
Views: 253
Reputation: 9484
It is working as it is supposed to work.
DispatchQueue.main.asyncAfter
is an async function, i.e. when you are calling the self.test
, the function returns after asking main thread to asynchronously wait for 10 seconds, and then immediately you ask the function to do the same for second time.
If you want the function to wait for the first execution, one way to do this is to call the function for second time in its completion handler:
self.Test(completionHandler: { finished in
print("We have completed function)")
self.Test(completionHandler: { finished in
print("We have completed function)")
})
})
EDIT: code in playground. Prints second function after about 10 seconds.
class TestAsyncAfter {
func nextStep(){
DispatchQueue.main.asyncAfter(deadline: .now() + 10.0) {
self.goToPage(completionHandler: { finished in
print("We have completed function")
})
}
}
func goToPage(completionHandler: @escaping (_ finished: String?) -> Void) {
completionHandler("finished")
}
}
let test = TestAsyncAfter()
test.goToPage(completionHandler: { finished in
print("We have completed function")
test.nextStep()
})
PlaygroundPage.current.needsIndefiniteExecution = true
Upvotes: 1