Become a member
to unlock all features

Level Up!

Access all courses & lessons on egghead today and lock-in your price for life.


    Convert a callback to a promise

    Will ButtonWill Button

    Promises are rapidly overtaking callbacks in popularity. In this lesson, I show you how to rewrite a callback using ES6 Promises. After getting a handle on the basics, we'll convert an error-first style callback to use the Resolve and Reject handlers built into Promises. If you aren't familiar with Promises, this lesson can be a great starting point by learning how to duplicate the behavior of a callback with ES6 Promises.



    Become a Member to view code

    You must be a Member to view code

    Access all courses and lessons, track your progress, gain confidence and expertise.

    Become a Member
    and unlock code for this lesson




    On the screen, I've got a really basic callback function and let me start just by showing you how that works by calling a Node command and passing in the name of that file. It starts off by calling the start function and that writes out to the log calling the wait function, and then calls the wait function passing in two parameters, a timeout, and the callback.

    When that wait function is called, it writes out to the console that it's waiting, starts the timeout. When that timeout completes, it writes out to the console, "Done waiting," and calls the callback which is this end function and writes out, "Finished waiting." How can we create this in a promise? Let's start by creating our wait function again. This time, it's just going to have a single parameter of the delay.

    It's going to write out to the console that it's waiting, and then we're going to return a new promise that has resolve parameter, and then we're going to have our setTimeout function. Like before, it will write out to the console upon completion that it's done waiting. We're going to call that resolve method that we passed in. We'll give it a delay and then close everything out.

    Next, let's create our start function. It has no parameters and it will be almost identical to the callback based version, the difference being that it only has one parameter to call for the wait function. After that, we're going to use the .then to call the end function when that promise has been resolved. We need to create our end function, so I'll do that.

    It's identical because it's just simply going to write out that it's finished waiting. Now, if we run that Node followed by the name of the file, which is promise.js, and we execute it, it starts off with calling the start method which writes out that it's calling the wait function. The wait function writes out that it's waiting.

    Whenever that timeout expires, the promise is resolved then it writes out the phrase, "Done waiting," and then triggers the .then methods which calls our end function to write out that it's finished waiting, so functionally, it's identical to our callback. Hopefully, a lot of the callback she deals with follows the error first model. I've modified our callback here on the left to reflect that.

    What that means is that our callback accepts two parameters an error object and response object and whenever we call it, for example, in my wait function, I modified it to check to see that the delay we passed in is actually a number. If it's not, then we're going to error out that callback. We call the callback with the first parameter as our error message.

    If we do get a number, then we're going to execute it as normal. When we call the callback, it will provide null as that first parameter because there's not an error, and then our response as the second parameter. How can we duplicate that logic over in our promise? The first thing we'll do is we will add a reject parameter. We'll do the same check to see if our delay is a number.

    If it's not, we're going to call that reject method and provide a string saying that it's not a number. Otherwise, we'll execute our timeout. We'll change the four banning a little bit, move my console log statement that we're waiting down into the L section of our block.

    I'm going to get rid of this console log saying that we're done waiting, because instead, we're going to return that as part of our resolve handler. Now, we'll go down to our start method here. We'll call wait, provide the parameter. We'll call our .then method. This time, we're going to give it a parameter to pass into a function.

    We're going to logout that response. Since this was the successful resolve, that response is actually going to be this text here, "Done Waiting." We'll call our end function. We're going to use the .catch method and it's going to have a parameter called error that goes to its function, which it's just going to logout.

    If we go to our bottom console window, we can run this with Node promise.js. We call our wait function, we're waiting, and done waiting, and finished waiting just as before. The exception here now is if I don't provide a number, instead I provide a string to the wait function. When I run that again, it calls the wait function and errors out using the promise reject handler saying that it's not a number.