Skip to content

Latest commit

 

History

History
314 lines (289 loc) · 11.9 KB

4.3 Creating Promises.md

File metadata and controls

314 lines (289 loc) · 11.9 KB

Callback, Promises & Async

Callback = the default JS technique for Asynchronous work:

  • Passes a function() into another function
  • Calls the call back() function at some time later, when some conditions have been met.
  • EXAMPLE:
function loadImage(scr, parent, callback) {
 var img = document.createElement('img');
 img.src = src;
 img.onload = callback;
 parent.appendChild(img);
};
  • NOTE: Althoug a callback() function works fine, it is not a solution for everything:

Callbacks vs Thens

Remaining questions are: Any operation could fail at any time

  1. How to handle errors?
  • JavaScript error: undefined is not a function.
  • Network error: network request error. NOTE: Althoug Node.js makes Async obligatory, but it is still the full responsibility of the coder to define and implement a code error strategy.
  1. How to create a work sequence?
  • Instead of creating a function into another function into another callback function, - known as the Paramid of DOOM,
  • it is better to create a good work sequence.
  • EXAMPLE: Paramid of DOOM
loadImage('above-the-fold.jpg', imgContainer, function() {
  loadImage('just-below-the-fold.jpg', imgContainer2, function() {
   loadImage('further-down-fold.jpg', imgContainer3, function() {
    loadImage('this-is-ridiculous.jpg', imgContainer4, function() {
     loadImage('abstract-art.jpg', imgContainer5, function() {
      loadImage('egyptian-pyramids.jpg', imgContainer6, function() {
       loadImage('last-below-the-fold.jpg', imgContainer7, function() {
        })
       })
      })
     })
    })
   })
  })
 })
})

Promises

  • Now see the same kind of code written with Promises.

  • EXAMPLE: Promises

var sequence = get('example.json')
 .then(doSomething)
 .then(doSomethingElse);
  • This is so much easier!

PROMISES Course Stages:

  1. Wrapping stage= the syntax of constructing promises.
  2. Thening stage = How to react to the resolution of a promise: ACTIONS TO TAKE.
  3. Catching stage = If something breaks, catch the error: RECOVERY TO MAKE.
  4. Chaining stage = Create a long sequences of asynchronous work: ASYNC TO MAKE.

PROMISES States:

  1. Fulfilled (Resolved). => The action related to the promise succeeded. RESOLVED: It works.
  2. Rejected. => The action related to the promise failed. REJECTED: It DOES NOT work.
  3. Pending. => Promise has not yet fulfilled or rejected. PENDING: It is still waiting.
  4. Settled. => Promise has either fulfilled or rejected. SETTLED: Something happened.

EXAMPLE: Promises

  • First the Event fires
  • Second set The Event listerer
new Promise(function(resolve, reject) {
  resolve('hi'); // works
  resolve('bye');// can´t happen a second time
});

Promise resolves

  • First: Promise created
  • Second: Promis settled
  • Set action for resolution value = //on main thread and potentially "blocking" Promise
Try{
}.....{
....
}

Create first Promise

EXAMPLE: 1 Wrapping stage= the syntax of constructing promises.

function wait(ms) {
/*Your code goes here!
Instructions:
(1) Wrap this setTimeout in a Promise. resolve() in setTimeout's callback.
(2) console.log(this) inside the Promise and observe the results.
(3) Make sure wait returns the Promise too!
*/
window.setTimeout(function() {}, ms);
};
/* Uncomment these lines when you want to test! You'll know you've done it right when the message on the page changes.*/
// var milliseconds = 2000;
// wait(milliseconds).then(finish);

// This is just here to help you test.
function finish() {
	var completion = document.querySelector('.completion');
	completion.innerHTML = "Complete after " + milliseconds + "ms.";
};

ANSWER:

 function wait(ms) {
 	return new Promise(function(resolve) {
	console.log(this);
	window.setTimeout(function() {
	resolve();
	}, ms);
    });
};

	var milliseconds = 2000;
	wait(milliseconds).then(finish);

	function finish() {
	var completion = document.querySelector('.completion');
	completion.innerHTML = "Complete after " + milliseconds + "ms.";
};	

NOTE: The Scope of this inside the promise is the global object.

Async Scenarios: When to use Promises

When and where Promises are useful: EXAMPLE 1: Promises = useful

var data = get ('data.json');
data.onload = fucntion (){
analyze(this.responseText);
};

EXAMPLE 2: Promises = NOT NEEDED

hugeArrayOfImages.forEach(function(i) {
  makeSepia(i);
  });

EXAMPLE 3: Promises = NOT NEEDED

data.forEach(function(d) {
 var div = createDiv(d);
 body.appendChild(div);
});

EXAMPLE 4: Promises = useful

var worker = new Worker ('worker.js');
 worker.postMessage/data);
 worker.onmmessage = doSomething;
  • EXAMPLE: Promises= UNDEFINED
new Promise(function(resolve) {
  console.log('first');
  resolve();
  console.log('second');
}).then(function() {
  console.log('third');
});

Promise {: undefined}

  • You'll notice that 'first', 'second' and 'third' all get logged.
  • 'second' gets logged despite that it comes after resolve().
  • Pass a value or undefined through resolve() and reject() to .then and .catch.
  • The values aren't being passed to .then or .catch, but to the functions called by .then or .catch.

Async/Await

Async

PROMISES Course Stages:

readyState()

switch (document.readyState) {
 case "loading":
   // The document is still loading.
   break;
 case "interactive":
   // The document has finished loading. We can now access the DOM elements.
   // But sub-resources such as images, stylesheets and frames are still loading.
   var span = document.createElement("span");
   span.textContent = "A <span> element.";
   document.body.appendChild(span);
   break;
 case "complete":
   // The page is fully loaded.
   console.log("The first CSS rule is: " + document.styleSheets[0].cssRules[0].cssText);
   break;
}

TEST readyState()

function ready() {
// Credit to Jake Archibald
// https://github.com/jakearchibald/svgomg/blob/master/src/js/page/utils.js#L7
return new Promise(function(resolve) {
	function checkState() {
	if (document.readyState !== 'loading') {
	resolve();
   }
}
	document.addEventListener('readystatechange', checkState);
	checkState();
   });
};
	ready().then(wrapperResolved);

It checks the readyState() twice:

  1. when the readyState() event fires
  2. immediately

Wrap an XML

  • Catching stage = If something breaks, catch the error: RECOVERY TO MAKE.
function get(url) {
return new Promise(function(resolve, reject) {
	function checkState() {
	var req = new XMLHttpRequest();
	req.open('GET?, url);
	req.onload = function() {
	if (req.status == 200) {
	resolve(req.response);
	} else {
	reject(Error(re.statusText));
	};
      };
      req.send();
   });
 });
 
 windows.addEventListehner(?WebComponentsReady?, function() {
 home = document.querySelector('section-data-route="home"]');
 
 get('http://udacity.github.io/exoplanet-explorer/site/app/data/earth-like-results.json´)
 .then(function(response) {
   addSearchHeader(response);
   })
 .catch(function(error) {
   addSearchHeader('unknown');
   console.log(error);
   	});
    });
}) (document);   

WebTechnologies

Chaining stage = Create a long sequences of asynchronous work: ASYNC TO MAKE. In 2015 jQuery Promises are safe to use in every browser except for internet explorer and Operamini.

  • Include a polyfillor other fallbackon your production site.
  • New APIs are taking advantage of promises as well, like Service Worker API. They allow you to add a powerful control between your APP and the network. In this way you can make APPS that work offline.
  • the FETCH API uses native to simplify XML HTTP query requests.

Summary

  • Create Promises
  • Change Promises: create a Get() function, use .Then to do something with the retrieved data.
  • Include Catches to ensure proper error handling.
  • With the Promis API .Then also returns promises.
  • You can .then after 1) an initial promise, and .then after 2) .then.
  • Developers use the term thenableto describe promises & .then´s.
  • Any object that returns .then = thenable.
  • Anything thenable can become part of a chain of asynchronous work.
  • Promises are thenable as .then and .catches.
  • All the JS Libraries include thenable objects.
  • When creating a chain of asynchronous work, each subsequent link in the chain receives:
  1. the fulfilled value of the previous promise OR
  2. the return value of the previous .then() function .
  • In this way, you can collect work from one asynchronous method to the next.
  • Being able to change thenable´s is a powerful technique to simplify complex sequences of asynchronous work.

Resources Callback, Promises & Async:

Resources Web Technologies: