Unterschiedliche Rückrufe für Fehler oder Fehler als erstes Argument?

12

Wir (und der JS SO-Chatroom) hatten vor einigen Tagen ein Gespräch mit @rlemon über seine Little-XHR- Bibliothek zur Fehlerbehandlung.

Grundsätzlich wollten wir entscheiden, welches Fehlerbehandlungsmuster verwendet werden soll:

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

Oder:

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

Einer ist eher jQuery-artig, während der andere eher Node-artig ist. Einige sagen, dass das erste Muster Sie mehr über den Umgang mit Fehlern nachdenken lässt. Ich denke das Gegenteil, da Sie die andere Rückruffunktion vielleicht vergessen, während das Argument beim zweiten Muster immer da ist.

Gibt es eine Meinung / einen Vorteil / einen Nachteil zu diesen beiden Mustern?

Florian Margaine
quelle
xhr.get({ ... }, function (err, data) {})Zumindest das richtige Muster
Raynos

Antworten:

5

Das wirklich wichtige Merkmal ist die Stilkonsistenz, damit Sie Code im gleichen Stil schreiben und Annahmen zur Metaprogrammierung darüber treffen können, wie mit asynchronen Situationen umgegangen wird.

Ich persönlich bevorzuge

(err, data)weil es eine Standardmethode für den Umgang mit Dingen ist. Es ermöglicht die Funktionszusammensetzung.

after.mapVerwendet zum Beispiel dieses Muster. Also Code wie

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

kann vereinfacht werden

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

Ein weiterer Vorteil ist, dass Sie als letzten Parameter einen Callback übergeben können

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

Der Callback-Last-Ansatz ist ein netter API-Vertrautheitsansatz.

Ein weiterer Vorteil ist, dass Sie leicht vergessen können, den errorHandler in Ihrem Objektliteral festzulegen, oder ihn auf eine Art Standardfehlerhandler festlegen können.

Wenn Sie (err, data)es verwenden, werden Sie jedes Mal daran erinnert, darüber nachzudenken, wie Sie mit diesem Fehler effizient umgehen können.

Raynos
quelle
2

Generell erinnere ich mich gerne daran, dass explizit immer besser ist als implizit.

Wenn ich das benutze, bin ich normalerweise auf der Seite von expliziten successund failureFunktionen - Sie wissen genau, was Sie tun, sobald Sie diesen Code öffnen -, wenn erfolgreich Anrufe bearbeitet werden, während Fehler Anrufe behandeln, bei denen ein Problem aufgetreten ist.

Bei Verwendung einer einzelnen Methode dauert das Lesen der Alternative länger, wenn Sie diesen Code ändern. Außerdem würden Sie wahrscheinlich mit so etwas enden;

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

Und diese Art von Boilerplate wird schnell langweilig.

Ganz zu schweigen davon, dass ein neuer Entwickler, der die Codebasis eingibt, möglicherweise kein Problem damit sieht, wenn Sie vergessen, dieses Boilerplate hinzuzufügen, und wenn Sie beispielsweise nur den Erfolg behandeln. Aber wenn sie explizite Fehler- / Erfolgs-Rückrufe haben, können sie ziemlich schnell erkennen, dass Sie einen errorRückruf verpassen, und sich an die Arbeit machen, um damit umzugehen einen Weg finden, um mit Fehlern umzugehen ". Dadurch wirkt der Code weniger magisch.

Nathan Hoad
quelle
Es ist schwieriger zu erkennen, dass ein Fehlerrückruf fehlt, und es ist einfacher zu erkennen, dass der erste errParameter nicht verarbeitet wird
Raynos,
1

Rückrufe trennen

Wenn der xhr.get()Anruf erfolgreich ist, errist er redundant. Wenn der Anruf fehlschlägt. dataist überflüssig. Übergeben Sie nicht beide, anstatt den Client-Code zu zwingen, den Status des einen oder anderen zu überprüfen.

Wenn sich herausstellt, dass der Erfolg ein Teilerfolg sein kann, geben Sie dies separat an. Das Versagen ist normalerweise die Rettungsoption.

Ich habe mit Entwicklern zusammengearbeitet, die nur den Erfolgsfall behandeln, und in vielen Szenarien würde in diesem Fall die Implementierung eines Erfolgsrückrufs ausreichen. Ein Rückruf mit mehreren Zuständen wäre eine katastrophale Option für diese Art der Programmierung, da sie von Erfolg ausgehen würden.

JBRWilkinson
quelle