JavaScript: Promise w/ setTimeout(),
XMLHttpRequest and
fetch()
A JavaScript Promise object allows us to perform
asynchronous tasks, representing its eventual value.
The above promise icon is by Freepik from
https://www.flaticon.com
Promises became available in JavaScript as part of the ECMAScript 6 (ES6) specification.
We begin by creating an instance of the
Promise constructor, to which an anonymous
function is passed. The anonymous function takes two parameters - the
resolve()
and
reject()
methods. Async operation goes inside the anonymous function, which on
success calls resolve(), else invokes
reject().
The syntax generally looks as follows:
if(window.Promise) {
var promise = new Promise(function(resolve, reject) {
if(/*async operation success*/) {
resolve('Success');
}
else {
reject('Fail');
}
});
promise.then(function(response) {
console.log(response);
}, function(error) {
console.log(error);
});
}
Two methods are availed on instantiation of the
promise object, the
then()
and the
catch()
methods. The then() method takes two
callback functions as its arguments: the first function is called when
the promise is fulfilled, and the second when the promise is rejected.
Both functions have one argument: a fulfilment value previously passed
to resolve() for the first function and a
reason of rejection passed to reject() for
the second function. The catch() method
also handles rejection
promise.then(function(response) {
console.log(response);
}).catch(function(error) {
console.log(error);
});
but it will not be executed if the second function inside the
preceding then() is present. Invoking
catch() is also equivalent to calling
then(undefined,function) as shown below
promise.then(function(response) {
console.log(response);
}).then(undefined, function(error) {
console.log(error);
});
In this tutorial, we will explore (with examples) how to use the
setTimeout() method and the
XMLHttpRequest object with JavaScript
Promise; and lastly, the
Fetch API
which uses Promises.
Promise with setTimeout()
The isEven() method below creates a
promise on call of it using the
setTimeout() function. The created
promise will resolve if the argument passed to
isEven() is an even number (as the
number 12, below), else it gets rejected.
if(window.Promise) {
function isEven(n) {
var promise = new Promise(function(resolve, reject) {
setTimeout(function() {
if(n%2 == 0) {
resolve(n + ' is an even number');
}
else {
reject(n + ' is an odd number');
}
}, 1500);
});
return promise;
}
isEven(12).then(function(response) {
console.log(response);
}, function(error) {
console.log(error);
});
}
The resolved value gets printed into the browser's console as:
12 is an even number
Promise with XMLHttpRequest Object
Here, we will show how to use a promise to resolve/reject the outcome of an XMLHttpRequest.
We will retrieve some details about a TV show (say,
The Mandalorian) from
TVmaze using
one of its API listed
here.
The show ID of The Mandalorian is
38963.
We pass the URL (embedding the show id) as a second argument inside
the open() function.
if(window.Promise) {
var promise = new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.tvmaze.com/shows/38963');
xhr.onload = function() {
if (xhr.status == 200) {
resolve(xhr.response);
} else {
reject(Error(xhr.statusText));
}
};
xhr.onerror = function() {
reject(Error('error fetching JSON data'));
};
xhr.send();
});
promise.then(function(data) {
console.log(JSON.parse(data));
}, function(error) {
console.log(error);
});
}
The value of the resolved Promise object is parsed using the
JSON.parse()
method and printed into the console.
We can display the retrieved information in a page by populating some elements of the DOM. Add the below piece of HTML into the page.
<div style="width:350px;">
<img src="" style="width: 100%"/>
<span></span>
</div>
The image URL and the summary of the show from the retrieved data
are assigned to the src attribute of the
<img/> element and into the
contents of the <span/> element
respectively.
promise.then(function(data) {
let d = JSON.parse(data);
document.querySelector("img").setAttribute("src", d.image.original);
document.querySelector("span").innerHTML = d.summary;
}, function(error) {
console.log(error);
});
Promise with fetch() Method
fetch()
is a Promise-based method which retrieves information from the
network asynchronously. This method is defined in the global
Window scope and need no attachment to
any object for use.
A simple GET request using
fetch() looks as follows:
fetch("https://api.tvmaze.com/shows/38963", {method: 'GET'})
.then(res => {
console.log(res);
});
For GET request, passing the
{ method: 'GET' } request object is
optional. The below request works just fine.
fetch("https://api.tvmaze.com/shows/38963")
.then(res => {
console.log(res);
});
The promise returned is a
Response
object, which is but just an HTTP response and not the actual JSON
data we need.
To extract the JSON response on fulfilment of Promise, we need to
chain the json() method to the response
as shown below. The resolved result will be available inside the
subsequent then statement.
fetch("https://api.tvmaze.com/shows/38963")
.then(res => res.json())
.then(res => console.log(res));
You can also use the text() method in
place of json(), but you will need to
parse it into a JavaScript object using the
JSON.parse()
method.
fetch("https://api.tvmaze.com/shows/38963")
.then(res => res.text())
.then(res => console.log(JSON.parse(res)));