Kyle Simpson: So I'm going to give you a couple of real quick things that callbacks try to do. These are things that people have tried to do to solve some of the issues with callbacks. For example, here, we have the separate callbacks approach where I pass in a success handler and an error handler, and I expect that one or the other is called.
But this is even more implicit trust because I'm trusting that you're only going to call one and not the other. What happens if they call the success and the failure? What happens if they call the failure first and then later they call the success, or vice versa? How are we supposed to handle that kind of thing?
We're trusting that they're not going to. But how would we handle that if they did? What would your program do if both callbacks got called? It would probably break, so this doesn't really solve inversion of control, it just makes it worse. Then we have, this is commonly called note style, but I think that's a really bad name, we should call it error-first style code, which is when we pass in a single callback but we get an error function, this error parameter is the first parameter there on line 9.
The error parameter will be filled with something truthy if there was an error condition and it will be empty if there wasn't. So we find ourselves inside of our functions, and this happens a lot in node, we do this if else all over the place. Now we don't have two separate functions, but we still have one function, and let me ask you the question, what happens if they pass back both an error object and a success value?
How would your code react? You'd probably completely ignore the success value, because you'd be checking only for the error object. So, again, we really haven't done anything to actually solve the implicit trust issues that have been created by callbacks as a continuation style.
Kyle Simpson: Okay. Here's my little running example that I'm going to give you, calculating the meaning of life.
And here I'm doing so with nested callbacks, okay? So, the first callback is I'm calling on line 5. I'm saying, this getData function by the way, he just waits 1,000 seconds and then gives you your data right back. So, I'm saying 1,000 milliseconds from now, I want you to pass me 10 back.
I'll add 10 to 1, and my x will now be 11. Then 1,000 milliseconds from now, I want you to hand me 30 back, and I'll add 30 plus 1, so I'll have 31. 1,000 milliseconds from now, I want you to hand me back the string that says meaning of life is equal to the addition of 11 and 31, and you hand me back the answer and I print that out, which is the meaning of life is 42.
Okay. So it's these asynchronous steps that I'm doing that might have been AJAX calls or click handlers or any other form of stuff. And it should be evident in this code, that if we did not trust this getData function, we would have had a massive inversion of control trust issue.
There's also lots of problems that we have no error handling here. What happens if halfway through, it fails to send us back the value, where the program just hangs? You don't have any way of doing it. So, you have to construct all kinds of elaborate solutions to these problems that callbacks introduce.