JS 6
Promises
kinda
A Promise is an object, that resolves or rejects an asynchronous function and its value, it has the methods promise.then(), promise.catch() and promise.finally(), from Promise.prototype:
//resolve/reject arguments are the parameters in then(e) and catch(error)
const myPromise = new Promise(function (resolve, reject) {
let sampleData = [2, 4, 6, 8];
(sampleData[1]) ? resolve( "resolved string" ) : reject('An error occured!');
});
myPromise
.then(function (e) {
console.log(e); //"resolved string"
})
.catch(function (error) {
throw new Error(error); //if reject we get Error('An error occured!')
})
.finally(function () {
console.log('PROMISE COMPLETED'); //printed in any case
})
The .then() method can take 2 arguments, they are callback functions, for the Promise resolve and reject, while catch() has only one for handling errors:
const promise1 = new Promise(function (resolve, reject) {
(5> 10) ? resolve('Successo !') : reject("not prevented")
});
promise1.then(function (value, none) {
console.log(value) // "Successo!" (on resolve)
console.log(none ) // not prevented (on reject)
});
Promise.all() takes an iterable of promises as input, and returns a promise:
console.log( //Promise {<pending>}
Promise.all([1,2,3,4]) // [[Prototype]]: Promise
) // [[PromiseState]]: "fulfilled"
// [[PromiseResult]]: Array(4), [[Prototype]]: Array(0)
Promise.all() needs all its promises to be resolved, it will wait until all promises are fulfilled:
const p1 = Promise.resolve(3);
const p2 = 1337;
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("foo");
}, 5000);
});
//after 5 seconds we get
Promise.all([p1, p2, p3]).then((values) => {
console.log(values); //[3, 1337, "foo"]
});
We can use .catch() to check each single promise:
const ph1 = new Promise((resolve, reject) => {
setTimeout(() => resolve('p1_delayed_resolution'), 1000);
});
const ph2 = new Promise((resolve, reject) => {
reject(new Error('p2_immediate_rejection'));
});
Promise.all([
ph1.catch((error) => error),
ph2.catch((error) => error ),
]).then((values) => {
console.log(values[0]); // "p1_delayed_resolution"
console.error(values[1]); // "Error: p2_immediate_rejection"
})
//Promise.all([ph1, ph2]) would just get the Error p2
Api and Fetch()
Fetch() allows us to send network request and load information, without reloading the page, it returns a Promise:
//without an [options] the fetch() is just a GET downloading content from the url
let promise = fetch(url, [options]) //[options] can be methods/headers
At this stage we don't have a body yet, we check the HTTPS status for errors:
//response.ok refers to HTTP-status 200-299
let response = await fetch(url);
if (response.ok) {
let json = await response.json();
} else {
alert("HTTP-Error: " + response.status);
}
The response promise object provides methods to access it in various formats:
response.text() return the text/string of the response
response.json() parse the response as JSON
response.formData() – return the response as FormData object
response.blob() – return the response as Blob (binary data with type),
response.arrayBuffer() – return the response as ArrayBuffer (low-level binary data),
The response needs to await, for code that has yet to return we use async functions.
async function test2()
{
let url = 'https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits';
//without options this is a GET response object
let response = await fetch(url2);
//We then Parse it as a JSON()
let commits = await response.json();
console.log(response11)
console.log(commits)
console.log(commits[0].author.login);
}
test2()
We can use await on simple promises:
async function pleaseWait() {
const promise = new Promise((resolve, reject) => {
setTimeout(() => resolve(console.log('hello')), 1000)
})
await promise
console.log('world')
return 42
}
//hello (1 second) world (at the end)
Promises can only change from pending to fulfilled or pending to rejected. They cannot change from fulfilled back to pending or rejected back to pending.
The Blob object can represent data as a file-like object that doesn't need to be in a javascript-native format, like images.
The response.blob() method's promise renders an image with URL.createObjectURL().
//it will return empty("") if its prototype.type is opaque
async function blob(){
//it won't work with shortened URL
let response = await fetch(' https://www.cdc.gov/nceh/features/lightning-safety/lightning-safety_600v2px.jpg?_=99663 ');
//Promise to resolve in a Blob object
let blob = await response.blob();
//After creating an HTML tag
let img = document.createElement('img');
img.style = 'position:fixed;top:10px;right:10px;width:100px';
document.body.append(img);
//We go back to the URL
img.src = URL.createObjectURL(blob);
setTimeout(() => {
//removes it or revokes its URL call, necessary in case you don't need it anymore
img.remove();
URL.revokeObjectURL(img.src);
}, 3000);
}
The response interface returns the header read-only property object:
async function zero(){
let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits');
console.log( response.headers.get('Content-Type'));
//application/json; charset=utf-8
//We can also loop through the map-like key/value pairs
for (let [key, value] of response.headers) {
console.log(`${key} = ${value}`);
}
}
zero()
The bind() method allows us to keep THIS argument when in a callback function:
//We can also use this method on other objects
const person = {
firstName: "John",
lastName: "Doe",
fullName: function () {
return this.firstName + " " + this.lastName;
}
}
const member = {
firstName:"Hege",
lastName: "Nilsen",
}
let fullName = person.fullName.bind(member);
console.log( fullName ) //Hege Nilsen
//It won't appear in the member object as a method, its a single operation bind to the object
The Request() object will go from the client to the server:
//It will come with a method(Get if empty) and can be fetch()
async function finn(){
const request = new Request('https://www.mozilla.org/favicon.ico' );
console.log( request.method ) //GET method
fetch(request)
.then((response) =>{
console.log( response) //status and body
})
}
finn()
//if posting Object JSON you will need to stringify first
Some Promise() based exercises solutions
//the function returns a promise, it fetch() from API and can reject
const promisify = () => new Promise((resolve, reject) => {
this.api.request(text, (result) => {
result ? reject(result) : resolve();
})
})
return promisify() // try
.catch(promisify) // retry one
.catch(promisify) // retry two
//each catch will work for each reject
Last updated
Was this helpful?