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:
Remaining questions are: Any operation could fail at any time
- 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.
- 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() {
})
})
})
})
})
})
})
})
})
-
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:
- Wrapping stage=
the syntax of constructing promises
. - Thening stage =
How to react to the resolution of a promise
: ACTIONS TO TAKE. - Catching stage =
If something breaks, catch the error
: RECOVERY TO MAKE. - Chaining stage =
Create a long sequences of asynchronous work
: ASYNC TO MAKE.
PROMISES States:
- Fulfilled (Resolved). => The action related to
the promise succeeded
. RESOLVED: It works. - Rejected. => The action related to
the promise failed
. REJECTED: It DOES NOT work. - Pending. => Promise has
not yet fulfilled or rejected
. PENDING: It is still waiting. - 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{
}.....{
....
}
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
.
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 afterresolve()
.- Pass a value or
undefined
throughresolve()
andreject()
to.then
and.catch.
- The values aren't being passed to
.then
or.catch
, but to the functions called by.then
or.catch
.
PROMISES Course Stages:
- Thening stage =
How to react to the resolution of a promise
: ACTIONS TO TAKE. The readyState() in the document can beloading
,interactive
,complete
. - Network throttlingto test.
- More info Google Dev Network Conditions
- MDN document.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;
}
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:
- when the readyState() event fires
- immediately
- 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);
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
polyfill
or otherfallback
on 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 makeAPPS that work offline
. - the
FETCH API
uses native to simplifyXML HTTP query requests
.
- 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
thenable
to describepromises
&.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
ofasynchronous work
, each subsequent link in the chain receives:
- the fulfilled value of the previous promise OR
- 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.
- Getting to know asynchronous JavaScript: Callbacks, Promises and Async/Await
- JavaScript Promises
- Google Developers- JavaScript Promises: an Introduction
- JavaScript Promises for Dummies
- Asynchronous vs synchronous execution, what does it really mean?
- The Future of JavaScript
- Asynchronous JavaScript #1 - What is Asynchronous JavaScript?
- Issues with jQuery Promises: 10 June 2016 update! With the 3.0 release, jQuery promises now satisfy Promises/A+ compliance!
- You're Missing the Point of Promises - Domenic Denicola (Pre-jQuery 3.0)
- jQuery Deferred Broken - Valerio Gheri (Pre-jQuery 3.0)
- Q Style Promises
- They're an implementation of the Promises/A+ spec.
- $q service Documentation
- Browser Implementation
- Can I Use... - Promises
- ES2015 Promises Polyfill
- Q Library
- Bluebird Promises
- APIs that Use Promises()
- Service Worker API
- Fetch API
- Fetch API Walkthrough
- "Thenable" used in context of promises on MDN