// Accolades si plusieurs instructions
var f = (i) => {
		i + 1;
		return (i);
	};
// Appel classique par la suite
f (42);

// Pas d'accolades si une instruction qui constitue la valeur retournée
var f = (i) => i ++;

// Pas de parenthèses si un seul paramètre
var f = i => i ++;

// IIFE (retourne 42 immédiatement)
(i => { i ++; return (i); }) (41)

// Idem
(i => i ++) (41)

function Banner (message) {
	this.message = message;
	this.displayNormal = function () {
		// Dans la fonction de l'IIFE, this est l'objet window !
		(function f () { console.log (this.message); }) ();
	}
	this.displayArrow = function () {
		// Dans la fonction de l'IIFE, this est l'objet Banner
		(() => console.log (this.message)) ();
	}
}
// Affiche undefined car window n'a pas de propriété .message
new Banner ("Normal function").displayNormal ();
// Affiche "Arrow function"
new Banner ("Arrow function").displayArrow ();

// API
function asyncGetSomeData (n, callback) {
	console.log ("Getting some data...");
	window.setTimeout (() => {
		var i, numbers;
		numbers = new Array ();
		for (i = 0; i != n; i ++)
			numbers.push (i);
		callback (numbers);
	}, 2000);
}

function asyncComputeSomething (numbers, callback) {
	console.log ("Computing something...");
	window.setTimeout (() => {
		var i, s;
		s = 0;
		for (i = 0; i != numbers.length; i ++)
			s += numbers[i];
		callback (s);
	}, 2000);
}

function syncDisplaySomeResult (sum) {
	console.log (`And the result is: ${sum}`);
}

// Utilisation de l'API
asyncGetSomeData (10, (numbers) => {
	asyncComputeSomething (numbers, (sum) => {
		syncDisplaySomeResult (sum);
	})
});

// API
function asyncGetSomeData (n) {
	return (new Promise ((resolve, reject) => {
		console.log ("Getting some data...");
		window.setTimeout (() => {
			var i, numbers;
			numbers = new Array ();
			for (i = 0; i != n; i ++)
				numbers.push (i);
			resolve (numbers);
		}, 2000);
	}));
}

function asyncComputeSomething (numbers) {
	return (new Promise ((resolve, reject) => {
		console.log ("Computing something...");
		window.setTimeout (() => {
			var i, s;
			s = 0;
			for (i = 0; i != numbers.length; i ++)
				s += numbers[i];
			resolve (s);
		}, 2000);
	}));
}

function syncDisplaySomeResult (sum) {
	console.log (`And the result is: ${sum}`);
}

// Utilisation de l'API
asyncGetSomeData (10).then (asyncComputeSomething).then (syncDisplaySomeResult);

// API
function asyncLoadTXT (url) {
	return (new Promise ((resolve, reject) => {
		var request;
		request = new XMLHttpRequest ();
		request.overrideMimeType ("text/plain");
		request.onreadystatechange = () => {
			if (request.readyState != 4)
				return;
			if (request.status != 200)
				reject (`HTTP error ${request.status} : ${request.statusText}`);
			else
				resolve (request.responseText);
		}
		request.open ("GET", url);
		request.send ();
	}));
}

// De la sorte, le client de l'API peut utiliser la fonction ainsi
asyncLoadTXT ("helloWorld.txt").then (result => console.log (result), reason => console.log (reason));

function asyncGetSomeData (n) {
	return (new Promise ((resolve, reject) => {
		console.log ("Getting some data...");
		window.setTimeout (() => {
			var i, numbers;
			numbers = new Array ();
			for (i = 0; i != n; i ++)
				numbers.push (i);
			resolve (numbers);
		}, 2000);
	}));
}

function asyncComputeSomething (numbers) {
	return (new Promise ((resolve, reject) => {
		console.log ("Computing something...");
		window.setTimeout (() => {
			var i, s;
			s = 0;
			for (i = 0; i != numbers.length; i ++)
				s += numbers[i];
			resolve (s);
		}, 2000);
	}));
}

function syncDisplaySomeResult (sum) {
	console.log (`And the result is: ${sum}`);
}