How to write your very own promise (for beginners)

A lot of novice programmers find the idea of promises difficult. I was no different, I understood the theory behind them, but truly had no idea how implement one properly, let alone write my own. That being said, let’s dive right into the theory and then learn how to write our own simple promise!

So, what is a promise anyways

What is a promise? Initially this was a tough question to answer. Many developers can tell you all about what has been colloquially refereed to as the JS callback hell. Sometimes, it’ll look something like this

So the question becomes, how can we make this more readable? Many novice developers have already come across AJAX with jQuery and used a promise without even knowing! Promises are simply a way of holding the JS event loop from running subsequent code until it has completed it’s purpose. You mostly see this with AJAX: I need to analyze some data from another server, however, since JS is designed in such a way that it will try to analyze the data when it is not even ready, I need something to wait and check when the data has been completely received. Promises turn that nasty callback cluster into something like this:

$.ajax({//grab some url}).then(function(data){ 
        //do something with data
}).then(function(data) {
       //do something else with data
})

So let’s jump to it, how can we write our own promise? Let’s start with defining our promise

Now let’s go ahead and define what a promise will be!

function MyPromise(func) {
//not the best idea to use _this, but easy to illustrate where //context should be 
_this = this;
this.state = ‘pending’
this.callback = null;
this.results;
func();
//we will call func right away to start the download, check below!
}

Now let’s define our vanilla HTML request

//start with an 'iife' so we can call $$ later
var $$ = (function() {
var ojQuery = {};
ojQuery.ajax = function(obj) {
//returns our HTML request

return new MyPromise(function(resolve, reject ) {
var xhr = new XMLHttpRequest();
xhr.open(obj.method, obj.url, true);
xhr.onload = function() {
if (xhr.status === 200 && xhr.readyState === 4) {
//notice how we set _this.state to resolved when done this will come in play later
if(_this.state !== ‘resolved’) {
_this.state = ‘resolved’;
console.log(xhr)
console.log(_this)
_this.results = xhr
}
} else if(_this.state !== ‘failed’) {
_this.state = ‘failed’
_this.results = xhr
}
return xhr;
};
xhr.send();
})
}
return ojQuery;
})();

And now let’s go ahead and write our loop to check for if our data has been sent

MyPromise.prototype.resolve = function(value) {
console.log(value)
_this.callback(value.response, value.statusText, value.status)
}
MyPromise.prototype.done = function(cb) {
//here we set an interval to check if the data has finished.
//remember earlier when we set _this.state to resolved? This will //only happen when the data is done being received. In such a case, //our callback can be called with our data.
var go = setInterval(function() {
if(_this.state === ‘failed’) {
clearInterval(go);
return;
}
if(_this.state === ‘resolved’) {
clearInterval(go)
_this.callback = cb;
_this.resolve(_this.results)
}
},1)
}

Voila, you’ve done it. Congrats! Time to go get started! Now we can call this with

var ajax = $$.ajax({ method:'GET', url: my url }).done(function(data) {
console.log(data)
});