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() functionworks 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
undefinedthroughresolve()andreject()to.thenand.catch. - The values aren't being passed to
.thenor.catch, but to the functions called by.thenor.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
polyfillor otherfallbackon your production site. - New APIs are taking advantage of
promisesas 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 APIuses native to simplifyXML HTTP query requests.
- Create Promises
- Change Promises: create a
Get() function, use.Thento do something with the retrieved data. - Include
Catchesto ensure proper error handling. - With the Promis API
.Thenalso returns promises. - You can .then after 1) an
initial promise, and .then after 2).then. - Developers use the term
thenableto describepromises&.then´s. - Any object that returns
.then= thenable. - Anything thenable can become part of a chain of
asynchronous work. - Promises are thenable as
.thenand.catches. - All the JS Libraries include thenable objects.
- When creating a
chainofasynchronous 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
