Retornos de chamada diferentes para erro ou erro como primeiro argumento?


12

Nós (e a sala de bate-papo do JS SO) conversamos com o @rlemon alguns dias atrás sobre sua biblioteca Little-XHR sobre tratamento de erros.

Basicamente, queríamos decidir qual padrão de tratamento de erros deve ser usado:

xhr.get({
    // Some parameters, and then
    success: function(data) {},
    failure: function(data) {}
})

Ou:

xhr.get({
    // Some parameters, and then
    callback: function(err, data) {}
})

Um é mais parecido com jQuery, enquanto o outro é mais parecido com um nó. Alguns dizem que o primeiro padrão faz você pensar mais sobre como lidar com erros. Penso o contrário, pois você pode esquecer a outra função de retorno de chamada, enquanto o argumento está sempre presente no segundo padrão.

Alguma opinião / vantagem / desvantagem sobre esses dois padrões?


xhr.get({ ... }, function (err, data) {})Pelo menos obter o padrão certo
Raynos

Respostas:


5

O recurso realmente importante é a consistência do estilo, para que você possa escrever código no mesmo estilo e faça suposições de meta-programação sobre como as situações assíncronas são tratadas.

Eu pessoalmente prefiro

(err, data)porque é uma maneira padrão de lidar com as coisas. Permite a composição da função.

Por exemplo, after.mapusa esse padrão. Então codifique como

after.map(["foo.js", "bar.js"], function (fileName, callback) {
    fs.readFile(fileName, function (err, file) {
        callback(err, file)
    })
}, function (err, files) {
    // handle files
})

pode ser simplificado para

after.map(["foo.js", "bar.js", fs.readFile, function (err, files) {
    // handle files
})

Outra vantagem é que você pode transmitir um retorno de chamada como último parâmetro

asyncOperation(options, function (err, data) {
    // not nested inside an object literal
})

A última abordagem de retorno de chamada é uma boa abordagem de familiaridade da API.

Uma vantagem adicional é que você pode facilmente esquecer de definir o errormanipulador no literal do objeto ou configurá-lo para algum tipo de manipulador de erro padrão.

Quando você o usa, (err, data)ele lembra que você deve sempre pensar em como lidar com esse erro com eficiência.


2

Geralmente, gosto de lembrar que o explícito é sempre melhor do que o implícito.

Usando isso, eu normalmente ficaria do lado de funções successe explícitas failure- você sabe exatamente com o que está lidando no momento em que abre o código - o sucesso lida com chamadas concluídas com êxito, enquanto o erro lida com chamadas com problemas.

A alternativa, usando um único método, levará mais tempo para ler quando você modificar esse código. Além disso, você provavelmente acabaria com algo assim;

xhr.get({
    callback: function(err, data) {
        if (err) {
            // handle that error somehow
        }
        else {
            // deal with success somehow
        }
    }
})

E esse tipo de clichê fica chato, rápido.

Sem mencionar, se você esquecer de adicionar este padrão, e por exemplo, você está apenas lidando com sucesso, então um novo desenvolvedor que entra na base de código pode não ver um problema com ele. Mas, com retornos de chamada de erro / sucesso explícitos, eles poderão ver rapidamente que você está perdendo um errorretorno de chamada e começar a trabalhar em uma maneira de lidar com isso, ou pelo menos descobrir "bem, isso é apenas lidar com o sucesso - devo encontre uma maneira de lidar com erros ". Faz o código parecer menos mágico.


sua mais difícil de ver o seu perder uma chamada de retorno de erro e mais fácil de ver o seu não lidar com o primeiro errparâmetro
Raynos

1

Retornos de chamada separados

Se a xhr.get()chamada for bem-sucedida, errserá redundante. Se a chamada falhar. dataé redundante. Em vez de forçar o código do cliente a verificar o estado de um ou de outro, não passe os dois.

Se o sucesso puder representar sucesso parcial, indique-o separadamente. A falha geralmente é a opção de resgate.

Trabalhei com desenvolvedores que apenas lidam com o caso de sucesso e, em muitos cenários, apenas a implementação de um retorno de chamada de sucesso seria suficiente nesse caso. Um retorno de chamada de vários estados seria uma opção catastrófica para esse estilo de programação, pois eles assumiriam sucesso.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.