JavaScript Promise general overview
I have not yet got around to writing a post that is a general overview of Promises in javaScript just a whole lot of posts on various native methods of the Promise Object as well as various libraries and other native javaScript features surrounding the use of Promises. So then in todays post I will be putting and end to this by writing a post that will serve as a way to tie all of this together.
1 - JS Promise basics
To start off this post I will be taking a moment to write about some basics of Promises, as well as any and all related topics that might come up in the process of doing so. There is of course having at least some background when it comes to getting started with javaScript itself in general, as well as all kinds of various other topics that you should know before hand. As such I will not be getting into all the various little details that you show know before reading this, however I will be trying my best to keep things fairly simple in the basic getting started type section as always.
The source code examples in this post can be found on Github
If you are wondering if the source code examples in this post are stored somewhere on Github you would be right, they are in my test vjs Github repository. In that repository I also have all the source code examples for all my other posts on vanilla javaScript.
1.1 - Simple promise example using the Promise Constructor
For this basic getting started example with promises I am using the Promise Constructor with the new keyword as a way to create a new promise object to which I can call then and catch methods off of. When calling the constructor I pass a function as the first argument and it is in the body of the function where I will define the conditions that will result in the promise object resolving or rejecting. In the event that the function resolves the next then function will be called, in the event that the promise rejects it will then be the next catch function that will be called.
|
|
1.2 - Simple example of a callback function
Before promises it was callback functions that where used as a way to define some logic that will fire after an amount of time has passed. In many cases these functions will also be given some way of finding out if some kind of error has happened also. I could get into callback functions in detail, but maybe for now I should just go over a quick example of one using the setTiemout method.
|
|
1.3 - Simple example of making a Promise with something that uses a callback
When it comes to using some kind of method that uses a callback as a way to define some logic that will fire after it is done to create a promise that can be done by just calling the method in the body of a function that is given to the constructor. The only thing that needs to be done different beyond hat is that I just need to call resolve of reject inside the body of the callback function.
|
|
1.4 - A nodejs example of the Promise Constructor
Here I have an example of using the Promise constructor in nodejs with the file system module. For this example I am using the file system module to read file to which the location of which will be supplied by way of the first positional argument when calling the script. Because the path must be given by the user of this script when calling it from the command line with node, that means that there are all kids of errors that can happen. For example the user can just call the script and fail to given a path to a file, another thing that could happen is that a path can be given but it is to a folder rather than a file. Also on top of the fact that there are all kinds of things that can go wrong, there is also the fact that reading a file is something that might take a little while.
|
|
1.5 - Simple client side example of a Promise
Now for a client side javaScript example of using one or more Promises. There a a whole lot of different things that come to mind when it comes to making a basic client side example, but for this one I thought I would just go with some quick example that involves parsing some JOSN. One good thing about this is that the act of parsing json is something that can often result in some kind of error, mainly in the event that the string that is given is nit valid josn. So then in this example I made a parseJSON method that returns, you guessed it, a promise. Inside the body of the function that I pass to the Promise constructor I use the try catch statement to try to parse a given string of text, in the event that all goes when doing so the promise will resolve with the parsed object from the text string. In the event that the parsing does not go well that will result in an error, so then in the catch block of the try catch statement that is where I would want to call reject.
|
|
2 - Chaining of promises
Working with promises often involves preforming one task that is needed to complete first before proceeding to another task that is going to be started with the results of the first. Some times this will need to be done over and over again for a whole bunch of things each of which can take some time, and also possibly result in one or more errors that would need to be handled. This can be thought of as a kind of chaining of promises one after another. So then in this section I will be going over a few examples of basic chaining of promises.
2.1 - simple example of a promise chain
This simple example of a promise chain starts off by calling the resolve method of the Promise global. This is a method that will always return a resolved promises object. So then it will result in the next then function being called, which in the body of that I am returning another resolved Promise by way of the Promise.resolve method.
|
|
2.2 - The order of then and catch matters
When working out a Promise chain it is impotent to make sure that I am aware of the order of the then and catch function calls. For example if I have a catch call that will return a resolved promise in the event of a certain kind of error that is to be used by a then call above it that will result in that process being skipped.
|
|
2.3 - nodejs example of a chain using many methods that return a promise
Now for an example that will really do something that will helper to show what some kind of real project might involve with it comes to chaining promises. In this example I am using the util promisify method in nodejs to make it so that the stat, readFile, and writeFiel method of the nodejs built in file system module will return promises. More on this method in a later section and what it is a good idea to use in when working with nodejs, but for now there is just looking at what is going on with the chain.
|
|
3 - The nodejs promisify method in the utils module
In nodejs there is the util module, and in this module there is a util promisify method that can be used as a way to create a method that will return a promise from a method that uses old nodejs style call back functions. On nodejs built in module that is packed with methods that use this kind of callback function would be the nodejs file system module.
3.1 - Basic util promisify example
To get started with this promisify method there is creating a quick simple script that will just read a file and spit put the data of the file to the standard output of the console if all goes well using the read file method of the file system module that has been passed to the promisify method. To making this kind of script I would just need to start by requiring in the file system module, and then the promisify method of the utils module. At that point I can create a read file method by calling the promisify method and passing the read file method of the file system module as the first and only argument for the promisify method. The returned result of doing so is then a read file method that will return a promise when used, at which point I can call that and then start chaining then and catch calls off of the promise object.
|
|
3.2 - Not using promisify, and just using the fs.promises in late nodejs versions
If I do not care at all about supporting old versions of nodejs that do not all ready have native methods that return a promise in the file system module, then there is just doing that. In late versions of nodejs such as 16.x there is now a collection of native methods in the nodejs file system module that will already return a promise. These methods are contained in a promise object of the nodejs file system module.
|
|
|
|
3.3 - Monkey patching fs.promises
If at some point I want to support old versions of node again the promise object of the file system could be easily monkey patched. The general idea would be to just feature test for the promises object, and then use the util promisify method to create that method if it is not there to begin with. The process of doing monkey patching is generally frowned upon, except for these kinds of situations in which one is just trying to make sure that something that should be there is in fact there.
|
|
4 - Recursive functions that return a promise
Another thing that I end up having to do now and then is to create a kind of function that will not just return a promise, but will also call itself over and over again, until some kind of condition is meet that will cause it to stop. This seems to happen often enough for me to at least want to start a section on this sort of thing when it comes to functions that are called recursivly and also used and return promises.
4.1 - loop back folder function
For this example I have made a quick function that will read a current given folder, and then as long as it has not reached the root folder, continue to do so by calling the function itself again with revised arguments of course where the folder is the parent folder. For now I just want to have a function that will be used to just add things to an array for each folder moving back to the root folder.
|
|
5 - Conclusion
So then there is a lot to cover when it comes to promises in native javaScript, as well as various methods of interest in nodejs, and client side javaScript. If that was not enough there is a whole would of topics that branch off from promises such as old style callback functions, the event loop, and ways to go about having more than one event loop to work with.
I thing I did okay covering the basics of promises at least for what that is worth, but in order to really do this topic justice I am going to need to come back and do a little more editing at some point for this one. I all ready have a lot of things drafted out when it comes to just writing some additional advanced topics on promises that I did not get to just yet. Also I would like to have at least one of not more full project example sections at some point also.