One is more jQuery-like, while the other is more Node-like. Some say that the first pattern makes you think more about handling error. I think the opposite, since you may forget the other callback function, while the argument is always there on the second pattern.

Generally, I like to remember that explicit is always better than implicit.

Using this, I'd typically side with explicit success and failure functions - you know exactly what you're dealing with the moment you open that code up - success deals calls that finished successfully, while error deals with calls that had a problem.

The alternative, using a single method, will take longer to read when you go to modify that code. Besides, you'd likely end up with something like this;

Not to mention, if you forget to add this boilerplate, and for example, you're only handling success, then a new developer entering the code base may not see see a problem with it. But having explicit error/success callbacks, they'd be able to see pretty quickly that you're missing an error callback and start working on a way to handle it, or at least figure out "well, this is only handling success - I must find a way to handle errors". It makes the code seem less magical.

If the xhr.get() call succeeds, then err is redundant. If the call fails. data is redundant. Rather than forcing client code to check the state of one or the other, don't pass both.

If it turns out that success could represent partial success, indicate that separately. Failure is usually the bail-out option.

I've worked with developers that only ever handle the success case and in many scenarios just implementing a success callback would suffice in this case. A multi-state callback would be catastrophic option for that style of programming as they'd assume success.