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()
Response.body / response.json() / a specific property

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?