(press spacebar to continue)
#1
var title = ['Welcome', 'To', 'ES6']
.join(' ')
.toLowerCase()
#2
define "title" = create Array("Welcome", "To", "ES6")
then, implode with ' '
then, stringToLower
var title = ['Welcome', 'To', 'ES6']
.join(' ')
.toLowerCase()
Who decided this is Javascript?
Not much help...
Finalized in 2009
Object.keys() Date.toISOString() Date.now() JSON.parse() JSON.stringify() String.trim() Array.isArray() Array.indexOf() Array.forEach() Array.map() Array.filter()
Let's fast forward...
6 years since ECMAScript Version 5

Also known as...

Start using it now, or be left behind!
These are all popular and influential frameworks
They are all using ES6 now!
What about browser support?
November 2015
| IE10 | 7% |
|---|---|
| Safari 6 | 12% |
| IE11 | 16% |
| Safari 7 & 8 | 21% |
| Safari 9 | 54% |
| Chrome | 65% |
| Firefox | 74% |
| IE Edge | 84% |
Support will improve over time
Support will improve over time
fancyES6Code();
regularES5Code();
fancySassCode
regularCssCode
> babel main.js
// main.js
require("babel-core/register");
// ES6 here
<script src="babel-core/browser.js"></script> <script src="main.es6.js"></script>
.pipe(babel())
grunt.initConfig({
"babel": {}
})
25 new features
I love you
Stop staring at me
var myBestFriend = 'Barry'; if (true) { var myBestFriend = 'Anthony'; } console.log( myBestFriend ); // ???
What is logged to the console?
var myBestFriend = 'Barry';
if (true) {
var myBestFriend = 'Anthony';
}
console.log( myBestFriend ); // Anthony
What is logged to the console?
var numbers = [1, 5, 10]; // Add numbers together var result = 0; for (var i = 0; i < numbers.length; i++) { var number = numbers[i]; result += number; } console.log( result ); // 16 console.log( i ); // 3 console.log( number ); // 10
Limits variable to block scope
let myBestFriend = 'Barry';
if (true) {
let myBestFriend = 'Anthony';
console.log( myBestFriend ); // Anthony
}
console.log( myBestFriend ); // Barry
let numbers = [1, 5, 10]; let result = 0; for (let i = 0; i < numbers.length; i++) { let number = number[i]; result += number; } console.log( result ); // 16 console.log( i ); // undefined console.log( number ); // undefined
This is how most would expect var to behave
Use let instead of var
(unless you really need var scoping)
Value that cannot be altered
const myConstant = 'never changes'; myConstant = 'can I change it?'; // NO!
Use const instead of let
Guarantees references won't be overridden
If you need references overridden, use let
const testString = 'anthony';
testString.startsWith('a'); // true testString.startsWith('ant'); // true // Second parameter: position to begin searching testString.startsWith('thon', 2); // true
const testString = 'anthony';
testString.includes('tho'); // true // Second parameter: position to begin searching testString.includes('ant', 1); // false
const testString = 'anthony';
testString.endsWith('ony'); // true // Second parameter: clip string to this length testString.endsWith('hon', 1); // false testString.endsWith('a', 1); // true testString.endsWith('hon', testString.length - 1); // true
const friends = [ { name: 'Barry', species: 'Bear' }, { name: 'Anthony', species: 'Anteater' } ]; const myBestFriend = friends.find(function(friend) { return friend.name === 'Barry'; }); console.log( myBestFriend ); // { name: 'Barry', species: 'Bear' } const myBestFriendIndex = friends.findIndex(function(friend) { return friend.name === 'Barry'; }); console.log( myBestFriendIndex ); // 0
Converts objects to an array
const myArray = Array.from(notAnArray);
Works with either;
Array.from(document.querySelectorAll('img'));
Array.from(jQuery('img'));
Array.from("test"); // ["t", "e", "s", "t"]
const sentence = joinWords('I', 'love', 'Barry');
Create the joinWords function
function joinWords(word1, word2, word3) {
// Join the words and return them
}
function joinWords() {
const words = Array.prototype.slice.call(arguments);
// Join the words and return them
}
Use spread!
Allows expressions to be expanded into arguments
Represented by 3 dots
function joinWords(...words) {
// 'words' is an array!
// Join the words and return them
}
const sentence = joinWords('I', 'love', 'Barry'); // This works
const sentence = joinWords('I', 'love', 'Barry'); // This works
const words = ['I', 'love', 'Barry'];
const sentence = joinWords(words); // This doesn't work
Call joinWords with an array
// Could try alter joinWords function to accept an array?
const sentence = joinWords(words);
const sentence = joinWords.apply(null, words);
Use spread!
const words = ['I', 'love', 'Barry']; const sentence = joinWords(...words); const sentence = joinWords('I', 'love', 'Barry'); // Same thing!
const words = ['I', 'love']; const sentence = joinWords(...words, 'my', ...['friend', 'Barry']); const sentence = joinWords('I', 'love', 'my', 'friend', 'Barry'); // Same thing!
const words = ['I', 'love', 'Barry']; const wordsCopy = [...words];
const position = [50, 200];
I want 'x' and 'y' constants
const x = position[0]; const y = position[1];
Use destructuring!
const [x, y] = position;
Works with spreads
const [a, b, ...rest] = [1, 2, 3, 4, 5]; console.log( a ); // 1 console.log( b ); // 2 console.log( rest ); // [3, 4, 5]
Works even better with objects
function getPosition() {
return { x: 50, y: 200, z: 13 };
}
const { x, y } = getPosition();
const { z : zIndex } = getPosition();
console.log( zIndex ); // 13
const { a = 0 } = getPosition();
console.log( a ); // 0
function getPosition(something) {
const x, y, z;
// Do some calculation magic
// Populate x, y, z constants
// ES5
return {
x: x,
y: y,
z: z
};
// ES6
return {
x,
y,
z
};
// ES6
return { x, y, z };
}
const name = 'Bob'; const activity = 'running'; const place = 'library';
// ES5 const sentence = name + ' is ' + activity + ' to the ' + place;
// ES6
const sentence = `${name} is ${activity} to the ${place}`;
// ES5 const story = '"My name is ' + name + '" said ' + name + '.\n' + '"I\'m ' + activity + ' to the ' + place + '", he continued.\n' + 'Then ' + name + ' went ' + activity + ' to the ' + place + '.';
// ES6
const story = `"My name is ${name}" said ${name}.
"I'm ${activity} to the ${place}", he continued.
Then, ${name} went ${activity} to the ${place}.`;
function displayMessage(message) {
// Some magic here to display the message
}
function removeMessage(message) {
// Some magic here to remove the message
}
Stop duplicate messages from displaying
Stop duplicate messages from displaying
function displayMessage(message) {
// Some magic here to display the message
}
function removeMessage(message) {
// Some magic here to remove the message
}
Stop duplicate messages from displaying
const messagesDisplayed = [];
function displayMessage(message) {
// Some magic here to display the message
}
function removeMessage(message) {
// Some magic here to remove the message
}
Stop duplicate messages from displaying
const messagesDisplayed = [];
function displayMessage(message) {
messagesDisplayed.push(message);
// Some magic here to display the message
}
function removeMessage(message) {
// Some magic here to remove the message
}
Stop duplicate messages from displaying
const messagesDisplayed = [];
function displayMessage(message) {
messagesDisplayed.push(message);
// Some magic here to display the message
}
function removeMessage(message) {
messagesDisplayed.splice(messagesDisplayed.indexOf(message), 1);
// Some magic here to remove the message
}
Stop duplicate messages from displaying
const messagesDisplayed = [];
function displayMessage(message) {
if (messagesDisplayed.indexOf(message) > -1) {
return false;
}
messagesDisplayed.push(message);
// Some magic here to display the message
}
function removeMessage(message) {
messagesDisplayed.splice(messagesDisplayed.indexOf(message), 1);
// Some magic here to remove the message
}
Stop duplicate messages from displaying
const messagesDisplayed = [];
function displayMessage(message) {
if (messagesDisplayed.indexOf(message) > -1) {
return false;
}
messagesDisplayed.push(message);
// Some magic here to display the message
}
function removeMessage(message) {
messagesDisplayed.splice(messagesDisplayed.indexOf(message), 1);
// Some magic here to remove the message
}
Stop duplicate messages from displaying
const messagesDisplayed = [];
function displayMessage(message) {
// Check if message has already been displayed
if (messagesDisplayed.indexOf(message) > -1) {
return false;
}
messagesDisplayed.push(message);
// Some magic here to display the message
}
function removeMessage(message) {
// Remove message as displayed
messagesDisplayed.splice(messagesDisplayed.indexOf(message), 1);
// Some magic here to remove the message
}
A new type of object
const mySet = new Set();
Store unique values of any type
mySet.add('test');
mySet.add({ testObject: true });
Similar to an array, but easier to use:
mySet.has('test'); // true
mySet.delete('test');
mySet.clear();
mySet.size;
mySet.keys();
mySet.values();
mySet.entries();
mySet.forEach();
Stop duplicate messages from displaying
function displayMessage(message) {
// Some magic here to display the message
}
function removeMessage(message) {
// Some magic here to remove the message
}
Stop duplicate messages from displaying
const messagesDisplayed = new Set();
function displayMessage(message) {
// Some magic here to display the message
}
function removeMessage(message) {
// Some magic here to remove the message
}
Stop duplicate messages from displaying
const messagesDisplayed = new Set();
function displayMessage(message) {
messagesDisplayed.add(message);
// Some magic here to display the message
}
function removeMessage(message) {
// Some magic here to remove the message
}
Stop duplicate messages from displaying
const messagesDisplayed = new Set();
function displayMessage(message) {
messagesDisplayed.add(message);
// Some magic here to display the message
}
function removeMessage(message) {
messagesDisplayed.delete(message);
// Some magic here to remove the message
}
Stop duplicate messages from displaying
const messagesDisplayed = new Set();
function displayMessage(message) {
if (messagesDisplayed.has(message)) {
return false;
}
messagesDisplayed.add(message);
// Some magic here to display the message
}
function removeMessage(message) {
messagesDisplayed.delete(message)
// Some magic here to remove the message
}
const messagesDisplayed = new Set();
function displayMessage(message) {
if (messagesDisplayed.has(message)) {
return false;
}
messagesDisplayed.add(message);
// Some magic here to display the message
}
function removeMessage(message) {
messagesDisplayed.delete(message)
// Some magic here to remove the message
}
Pow!
What if hundreds of messages are displayed?
const testMessage = {
contents: 'Barry is such a handsome bear'
};
displayMessage(testMessage);
const importantMessage = {
contents: 'Anteaters suck',
important: true
};
displayMessage(importantMessage);
// etc... (hundreds of these)
What if hundreds of messages are displayed?
const messagesDisplayed = new Set();
function displayMessage(message) {
if (messagesDisplayed.has(message)) {
return false;
}
messagesDisplayed.add(message);
// Some magic here to display the message
}
Similar to the Set object
Used for storing objects
Use Weak Sets when storing objects
const weakSet = new WeakSet(); weakSet.add(object); weakSet.has(object); weakSet.delete(object);
const myMap = new Map();
myMap.set('testKey', 'testValue');
May have used objects in ES5
const myMap = {
'testKey': 'testValue'
}
Maps are more readable, and easier to use
const myMap = new Map();
myMap.set('testKey', 'testValue');
myMap.has('testKey'); // true
myMap.get('testKey'); // 'testValue'
myMap.delete('testKey');
myMap.clear();
myMap.size;
myMap.keys();
myMap.values();
myMap.entries();
myMap.forEach();
The same concept as Weak Set
const weakMap = new WeakMap(); weakMap.set(object, value); weakMap.has(object); weakMap.get(object); weakMap.delete(object);
The keys are weak, not the value
Iterating arrays in ES5
Lots of choices
None are great
for (var index = 0; index < myArray.length; index++) {
var value = myArray[index];
// ...
}
myArray.forEach(function(value, index) {
// ...
});
for (var index in myArray) {
var value = myArray[index];
// ...
}
Iterating arrays in ES6
One choice
It's great!
for (let value of myArray) {
// ...
}
for (let index of myArray.keys()) {
// ...
}
for (let [index, value] of myArray.entries()) {
// ...
}
Works for any iterable object
For everything else, either;
function displayMessage(content, priority = 1) {
console.log(`Priority: $(priority)`);
// Some magic here to display the message
}
displayMessage('Hello, I am a message'); // Priority: 1
displayMessage('Something went wrong!', 10); // Priority: 10
Always put default parameters last
Avoid using too many parameters
function displayMessage(content, priority = 1, position = { x: 0, y: 0 }, title = null) {
// Some magic here to display the message
}
displayMessage('Default message');
displayMessage('Centered message', 1, { x: '50%', y: '50%'});
displayMessage('Error message with title', 10, { x: 0, y: 0 }, 'Uh oh');
Use destructuring!
function displayMessage(content, { priority = 1, position = { x: 0, y: 0 }, title = null } = {}) {
// Some magic here to display the message
}
displayMessage('Default message');
displayMessage('Centered message', {
position: { x: '50%', y: '50%' }
});
displayMessage('Error with title', {
priority: 10,
title: 'Uh oh'
});
Boom!
const defaultMessage = {
content: 'Default message'
};
const centeredMessage = {
content: 'Centered message',
position: { x: '50%', y: '50%' }
};
const errorMessage = {
content: 'Error message with title',
priority: 10,
title: 'Uh oh'
};
Is there a better way to represent a message?
Custom type of object
Has its own functions and properties
const myObject = new Object();
const myArray = new Array();
const myCustomObject = new CustomObject(); myCustomObject.exampleFunction(); myCustomObject.exampleProperty = 'testing'; console.log( myCustomObject.exampleProperty ); // 'testing'
class CustomObject {
exampleFunction() {
this.exampleProperty = 'testing';
}
anotherExampleFunction() {
this.exampleFunction();
}
}
class Message {
getContent() {
return 'Hello, I am a message';
}
}
const myMessage = new Message();
console.log( myMessage.getContent() ); // Hello, I am a message
Class names should be UpperCamelCase
All these lines of code to create messages?!
// Create test message class TestMessage { getContent() { return 'Hello, I am a test message'; } } const myTestMessage = new TestMessage(); // Create error message class ErrorMessage { getContent() { return 'Something went wrong!'; } } const myErrorMessage = new ErrorMessage();
A class represents a template for creating objects
Just one class / template: Message
const myTestMessage = new Message(); myTestMessage.setContent('Hello, I am a test message'); const myErrorMessage = new Message(); myErrorMessage.setContent('Something went wrong!');
console.log( myTestMessage.getContent() ); // Hello, I am a test message! console.log( myErrorMessage.getContent() ); // Something went wrong!
class Message {
setContent(content) {
this.content = content;
}
getContent() {
return this.content;
}
}
Aw yeah!
const myMessage = new Message(); myMessage.setContent('Hello, I am a test message'); myMessage.content = 'Hello, I am a test message'; console.log( myMessage.getContent() ); console.log( myMessage.content );
class Message {
set content(content) {
this.content = content;
}
get content() {
return this.content;
}
}
I see a bug!
class Message {
set content(content) {
this.content = content;
}
}
This may make it easier to spot
class Message {
setContent(content) {
this.setContent(content);
}
}
Maximum call stack size exceeded
class Message {
set content(content) {
this.content = content;
this._content = content;
}
get content() {
return this.content;
return this._content;
}
}
This seems like a lot of work... why bother?
You're right!
A regular object does getters and setters
const myMessage = new Object(); myMessage.content = 'Hello, I am a test message'; console.log( myMessage.content ); // Hello, I am a test message
class Message {
// Empty
}
const myMessage = new Message(); myMessage.content = 'Hello, I am a test message'; console.log( myMessage.content ); // Hello, I am a test message
Let's get clever with classes
class Message {
set priority(priority) {
if (priority < 1 || priority > 10) {
throw new Error('Priority must be between 1 and 10');
}
this._priority = priority;
}
}
const myMessage = new Message(); myMessage.priority = 20; // ERROR: Priority must be between 1 and 10 myMessage.priority = 5;
class Message {
get log() {
return `${this.timestamp} - [${this.priority}] ${this.content}`;
}
}
const myMessage = new Message(); myMessage.timestamp = new Date(); myMessage.priority = 5; myMessage.content = 'Hello, this is a test message'; console.log( myMessage.log ); // Mon Nov 16 2015 20:24:01 GMT+0000 (GMT) - [5] Hello, this is a test message
Wouldn't it be nice if timestamp was automatically set?
Special function named constructor
Automatically runs when the class is created
class Message {
constructor() {
this.timestamp = new Date();
}
}
const myMessage = new Message(); console.log( myMessage.timestamp ); // Mon Nov 16 2015 20:24:01 GMT+0000 (GMT)
Construtors accept parameters too
class Message {
constructor(content) {
this.timestamp = new Date();
this.content = content;
}
}
const myTestMessage = new Message('Hello, this is a test message');
const myErrorMessage = new Message('Something went wrong!');
Allows a class to inherit everything from another class
class DebugMessage extends Message {
// Empty
}
class ErrorMessage extends Message {
// Empty
}
const myDebugMessage = new DebugMessage('I am a debug message');
const myErrorMessage = new ErrorMessage('I am an error message');
Everything still works!
class Message {
setContent(content) {
this.content = content;
}
}
class ErrorMessage extends Message {
setContent(content) {
content = content + '!!!';
super.setContent(content);
}
}
const myMessage = new Message('I am a message');
console.log( myMessage.content ); // I am a message
const myErrorMessage = new ErrorMessage('I am an error message');
console.log( myErrorMessage.content ); // I am an error message!!!
class Message {
set content(content) {
this._content = content;
}
}
class ErrorMessage extends Message {
set content(content) {
content = content + '!!!';
super.content = content
}
}
class Message {
constructor(content) {
this.content = content;
this.priority = 5;
}
}
class DebugMessage extends Message {
constructor(content) {
super(content);
this.priority = 1;
}
}
const myMessage = new Message('I am a message'); console.log( myMessage.priority ); // 5 const myDebugMessage = new DebugMessage('Just testing'); console.log( myErrorMessage.priority ); // 1
New syntax to easily create anonymous functions
// ES5
const debugMessages = messages.filter(function(message) {
return message.priority === 1;
});
// ES6
const debugMessages = messages.filter((message) => {
return message.priority === 1;
});
const debugMessages = messages.filter((message) => {
return message.priority === 1;
});
const debugMessages = messages.filter((message) => message.priority === 1);
const debugMessages = messages.filter(message => message.priority === 1);
// ES5 anonymous function
function(param1, param2) {
// ...
}
// ES6 arrow function
(param1, param2) => {
// ...
}
They look different... so what?
What's wrong with this code?
class Message {
constructor() {
this.priority = 5;
}
increasePriorityEverySecond() {
setInterval(function() {
this.priority = this.priority + 1;
}, 1000);
}
}
What's wrong with this code?
class Message {
constructor() {
this.priority = 5;
}
increasePriorityEverySecond() {
setInterval(function() {
this.priority = this.priority + 1;
}, 1000);
}
}
class Message {
increasePriorityEverySecond() {
var self = this;
setInterval(function() {
self.priority = self.priority + 1;
}, 1000);
}
}
class Message {
increasePriorityEverySecond() {
setInterval(function() {
this.priority = this.priority + 1;
}.bind(this), 1000);
}
}
Arrow functions retain this from parent scope
class Message {
increasePriorityEverySecond() {
setInterval(() => {
this.priority = this.priority + 1;
}, 1000);
}
}
class Message {
increasePriorityEverySecond() {
setInterval(() => this.priority = this.priority + 1, 1000);
}
}
class Message {
increasePriority() {
this.priority = this.priority + 1
}
increasePriorityEverySecond() {
setInterval(() => this.increasePriority(), 1000);
}
}
Yessss
// Globals var myModule = window.myModule; // AMD / RequireJS define(['myModule'], function(myModule) { }); // CommonJS / npm module.exports = myModule; var myModule = require('myModule'); // ES6 export myModule; import { myModule } from 'myModule';
// Globals var myModule = window.myModule; // AMD / RequireJS define(['myModule'], function(myModule) {}); // CommonJS / npm module.exports = myModule; var myModule = require('myModule'); // ES6 modules export myModule; import { myModule } from 'myModule';
// message.js
export class Message {
// ...
}
// main.js
import { Message } from './message.js';
const myMessage = new Message();
// message-utils.js export function displayMessage(message) { // ... } export function removeMessage(message) { // ... }
import { displayMessage, removeMessage } from './message-utils.js';
import { removeMessage } from './message-utils.js';
import * as MessageUtils from './message-utils.js';
MessageUtils.displayMessage();
MessageUtils.removeMessage();
// /vendor/message.js
export class Message {}
// /app/message.js
export class Message {}
import { Message as MessageVendor } from '/vendor/message.js';
import { Message as MessageApp } from '/app/message.js';
One per module
// message.js
export default class Message {}
// main.js import NameItWhateverYouLike from './message.js'
ES6 only specifies a standard for
the import & export syntax
ES6 does not specify a standard for loading files
import { nope } from '../browser/does/not/know/how/to/load/this/file.js';
Solution
testInternetConnection(function() { fetchMessagesFromServer(function(messages) { messages = JSON.parse(messages); if (messages[0] === null) { displayError('Could not email first message'); logger.log('First message does not exist'); } else { sendEmail( 'test@example.com', 'Here is the first message: ' + messages[0], function() { displayMessage('Success!'); }, function(error) { displayError('Could not email first message'); logger.log('Error sending email: ' + error); } ); } }, function(error) { displayError('Could not email first message'); logger.log('Error fetching messages from server: ' + error); }); }, function(error) { displayError('Could not email first message'); logger.log('Internet connection test failed: ' + error); });
testInternetConnection({
onComplete: function() {
fetchMessagesFromServer({
onComplete: function(messages) {
messages = JSON.parse(messages);
if (messages[0] === null) {
displayError('Could not email first message');
logger.log('First message does not exist');
} else {
sendEmail({
email: 'test@example.com',
message: 'Here is the first message: ' + messages[0],
onComplete: function() {
displayMessage('Success!');
},
onError: function(error) {
displayError('Could not email first message');
logger.log('Error sending email: ' + error);
}
});
}
},
onError: function(error) {
displayError('Could not email first message');
logger.log('Error fetching messages from server: ' + error);
}
});
},
onError: function(error) {
displayError('Could not email first message');
logger.log('Internet connection test failed: ' + error);
}
});
testInternetConnection()
.done(function() {
fetchMessagesFromServer()
.done(function(messages) {
messages = JSON.parse(messages);
if (messages[0] === null) {
displayError('Could not email first message');
logger.log('First message does not exist');
} else {
sendEmail({
email: 'test@example.com',
message: 'Here is the first message: ' + messages[0]
})
.done(function() {
displayMessage('Success!');
})
.error(function(error) {
displayError('Could not email first message');
logger.log('Error sending email: ' + error);
});
}
})
.error(function(error) {
displayError('Could not email first message');
logger.log('Error fetching messages from server: ' + error);
});
})
.error(function(error) {
displayError('Could not email first message');
logger.log('Internet connection test failed: ' + error);
});
testInternetConnection()
.done(testInternetConnectionDone)
.error(testInternetConnectionError);
function testInternetConnectionDone() {
fetchMessagesFromServer()
.done(fetchMessagesFromServerDone)
.error(fetchMessagesFromServerError)
}
function testInternetConnectionError(error) {
displayError('Could not email first message');
logger.log('Internet connection test failed: ' + error);
}
function fetchMessagesFromServerDone(messages) {
messages = JSON.parse(messages);
if (messages[0] === null) {
displayError('Could not email first message');
logger.log('First message does not exist');
} else {
sendEmail({
email: 'test@example.com',
message: 'Here is the first message: ' + messages[0]
})
.done(sendEmailDone)
.error(sendEmailError);
}
}
function fetchMessagesFromServerDoneError() {
displayError('Could not email first message');
logger.log('Error fetching messages from server: ' + error);
}
function sendEmailDone() {
displayMessage('Success!');
}
function sendEmailError(error) {
displayError('Could not email first message');
logger.log('Error sending email: ' + error);
}
There's a better way...
function fetchMessagesFromServer() {
// This function takes time
// Return to caller a Promise object straight away
return new Promise(function(resolve, reject) {
// After some time has passed, update the Promise
// Two types of updates;
// 1. Resolve (yay) with a value
// 2. Reject (aw) with a value
jQuery.get('http://example.com/messages.json') // time passes
.done(function(result) {
// Update the Promise
// Resolve, and pass in the result
resolve(result);
})
.fail(function() {
// Update the Promise
// Reject, and pass in an error message
reject('Could not fetch messages from server');
});
});
}
const messages = fetchMessagesFromServer(); console.log( messages ); // Promise - what do I do with this?!
fetchMessagesFromServer() .then(function(value) { // Promise resolved console.log(value); }) .catch(function(value) { // Promise rejected console.log(value); });
So what?
fetchMessagesFromServer()
.then(function(messages) {
// ...
})
.catch(function(error) {
// ...
});
fetchMessagesFromServer(
function(messages) {
// ...
},
function(error) {
// ...
}
);
fetchMessagesFromServer({
onComplete: function(messages) {
// ...
},
onError: function(error) {
// ...
}
});
fetchMessagesFromServer()
.done(function(messages) {
// ...
})
.fail(function(error) {
// ...
});
The power of Promises:
Chaining them together
The function within then() can do 3 types of things;
1. Return another promise
fetchMessagesFromServer()
.then(function(messages) {
const promise = sendEmail('test@example.com', messages);
return promise;
})
.then(function(email) {
// ...
})
.catch(function(error) {
// ...
});
The function within then() can do 3 types of things;
2. Return a value
fetchMessagesFromServer()
.then(function(messages) {
return messages[0];
})
.then(function(firstMessage) {
// ...
});
This is the same as resolving a Promise
The function within then() can do 3 types of things;
3. Throw an error
fetchMessagesFromServer()
.then(function(messages) {
// Try to do something a little crazy
throw new Error('Uh oh');
})
.catch(function(error) {
// ...
});
This is the same as rejecting a Promise
testInternetConnection() .then(function() { return fetchMessagesFromServer(); }) .then(function(messages) { return JSON.parse(messages); }) .then(function(messages) { if (messages[0] === null) { throw new Error('First message does not exist'); } else { return messages[0]; } }) .then(function(firstMessage)) { return sendEmail( 'test@example.com', 'Here is the first message: ' + firstMessage ); }) .then(function() { displayMessage('Success!'); }) .catch(function(error) { displayError('Could not email first messsage'); logger.log(error); });
class MessageService { fetchMessagesAsJson() { return testInternetConnection() .then(fetchMessagesFromServer) .then(JSON.parse); } } class MessageEmailer { _getFirstMessage(messages) { if (messages[0] === null) { throw new Error('First message does not exist'); } return messages[0]; } _emailMessage(email, message) { return sendEmail(email, 'Here is the message: ' + message); } send(email) { MessageService.fetchMessagesAsJson() .then(this._getFirstMessage) .then(firstMessage => this._emailMessage(email, firstMessage)) .then(() => displayMessage('Success!')) .catch((error) => { displayError('Could not email message'); console.log(error); }) } }
Yes, there are more...
http://github.com/iamturns/es6-presentation
| Summary | github.com/lukehoban/es6features |
|---|---|
| Detail | es6-features.org |
| 350 bullet points | ponyfoo.com/articles/es6 |
| Interactive lessons | learnharmony.org |
| TDD style lessons | es6katas.org |
| Reference | developer.mozilla.org |
Final message...
Do it for Barry