Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

259
Visualizações
Do we always need to call a completion handler inside a closure?

I have a completion handler that gets called inside my closure. However, the completion handler only gets called when everything goes well. In the case of an error, the completion handler never gets called.

func product(with id: String, _ completion: @escaping (Product) -> ()) {

     // Make a network request for the product
     ...

    if (product) {
       completion(product)
    }
}

Is this a bad design? I recently got the comment that completion handlers need to be called even in case of errors, otherwise the caller will be waiting indefinitely. I've never heard that before and now I'm wondering if this applies to Swift.

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

Strictly spoken the caller doesn't wait at all. The code in the closure will or will not be executed.

However it's good practice to return errors, too.

A smart way is the Result type

func product(with id: String, completion: @escaping (Result<Product,Error>) -> Void) {

     // Make a network request for the product
     ...
    if error = error { completion(.failure(error)); return }

    if product {
       completion(.success(product))
    } else {
       let error = // create some other error
       completion(.failure(error))
    }
}

And call it

product(with: "Foo") { result in
   switch result {
     case .success(let product): // do something with the product
     case .failure(let error): // do something with the error
   }
}

Note: The underscore character before completion in the function declaration is pointless.

over 4 years ago · Santiago Trujillo Relatório

0

If you will not call a completion nothing will happen 'cuz completion caller will not wait for it.

But if you want to cover all cases try to add a failure callback. For example:

func product(with id: String, _ success: @escaping (Product) -> (), failure: @escaping (Any) -> ())
over 4 years ago · Santiago Trujillo Relatório

0

In your case, if you are treating it as a completion, it means that it has to get called no matter what's case (success of failure with error), it has to returns when the process completed.

What you could do is to pass an optional error and product to the completion closure and then check whether the error is nil or not:

func product(with id: String, _ completion: @escaping (Product?, Error?) -> ()) {
    // in case of there is an error:
    completion(nil, error)
    return

    // if things went happy:
    completion(product, nil)
}

Calling the method:

product(with: "ID") { (product, error) in
    guard let returnedError = error else {
        print(product)

        return
    }

    print(returnedError)
}

Or:

product(with: "ID") { (product, error) in
    if let returnedError = error {
        print(returnedError)
        return
    }

    print(product)
}
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda