On Github JSWorkshops / async
Async programming in JS is hard.
/* Pyramid of DOOM! */
try{
var url = "someU.data";
showIndicator("fadein",
downloadData(url, function(data){
processData(rawData, function(data){
displayData(data, removeIndicator)
});
});
});
}catch(e){
console.log("argh... screw this!");
throw e;
}
photo by Alper Çuğun
var p1 = Promise.resolve("fulfilled!");
p1.then((msg) => console.log(msg)); // "fulfilled!"
var p2 = Promise.reject("rejected!");
p2.then(undefined, (msg) => console.log(msg)); // "Rejected!"
var p3 = new Promise((resolve, reject) => {
if (condition) resolve();
if (otherCondition) reject();
throw new Error("Error!");
});
//fulfill, reject, catch
p3.then(success, failure)
.catch(recover);
var p = new Promise((resolve,reject)=>{
//I'm on vacation in July!
if(new Date().getMonth() === 7){
reject(new Error("On vacation!"));
} else {
resolve("Yeah, do it!");
}
});
p.then(
successMsg => console.log(successMsg),
rejectMsg => console.log(rejectMsg)
);
function canIdoTheWork(date){
return (date.getMonth() === 7)?
Promise.reject(new Error("On vacation!"))
: Promise.resolve("Let's do this!");
}
canIdoTheWork(new Date()).then(
successMsg => console.log(successMsg),
rejectMsg => console.log(rejectMsg)
);
var barista = {
skills: new Set(['Americano', 'Latte']),
get mood() { return Math.round(Math.random()) },
makeCoffee(type = 'Americano') {
if (!this.skills.has(type)) {
return Promise.reject(new Error(`No ${type} for you!`));
}
return new Promise((resolve, reject) => {
// 1 second to make a coffee
setTimeout(() => { // 1 second to make a coffee
if(this.mood){
return resolve(`Here is your ${type}`);
}
reject(new Error("I quit!"));
}, 1000);
});
}
}
var success = msg => console.log(msg, "thanks!");
var fail = err => console.log(err);
//reject straight away!
barista.makeCoffee("milkshake").then(undefined, fail);
//Make me an Americano and a latte
barista.makeCoffee()
.then(() => barista.makeCoffee("Latte"))
.then(success).catch(fail);
var car1 = new Car("one"),
var car2 = new Car("two"),
var car3 = new Car("three"),
var carRace = [car1.drive(), car2.drive(), car3.drive()];
Promise.race(carRace).then(e => console.log(e));
Promise.all(carRace).then(data => console.log(data));
A zero arguments function that, when called:
// A zero arguments function that, when called:
obj[Symbol.iterator] = function() {
// Returns an object
return {
// has .next() method.
next() {
// that returns an object with:
return {
value: "", // value prop
done: trueOrFalse, // done prop
};
}
};
};
Hard to represent lazy lists in JS.
function* myGenerator(){
yield 1;
}
var genObj = myGenerator();
Yield control of execution at this point.
function* myGenerator(){
yield 1;
}
var genObj = myGenerator();
var result = myGenerator.next(); //run!
// result = Object { value: 1, done: false }
This looks familiar...
function* myGenerator(value){
yield 1;
return value;
}
var genObj = myGenerator("hello there");
var result = genObj.next(); //run!
// result = Object { value: 1, done: false }
result = genObj.next(); //keep going!
// result = Object { value: "hello there", done: true }
function* myGenerator(value){
let result = yield value;
return result;
}
var genObj = myGenerator("hello there");
var value = genObj.next().value; //first run!
genObj.next(value.toUpperCase());
console.log(genObj.next().value); // "HELLO THERE"
function* myGenerator(value){
let result = "";
try{
result = yield 1;
} catch (err) {
result = "recovered";
}
return result;
}
var genObj = myGenerator("hello there");
var result = genObj.next().value;
if(typeof result !== "string"){
result = genObj.throw(new TypeError("Expected a string"));
}
console.log(result.value); // "Recovered"
*terms and conditions apply.
fetch(url)
.then(response => response.json())
.then(json => processJson)
.catch(handleError)
.then(moarThen)
.catch(err => throw err)
async function getJSON(url){
let response = await fetch(url);
let result;
try{
let json = await response.json();
result = processJson(json);
} catch (err) {
result = attempToRecover(err);
}
return result;
}
getJSON(someURL)
.then(showIt)
.catch(handleError);
function* getURL(url){
//...
}
// Generator object - initializes closure
let getFoo = getURL("/foo");
function* getURL(url){
let response = yield fetch(url);
}
// Generator object - initializes closure
let getFoo = getURL("/foo");
let {value: promise} = getFoo.next();
function* getURL(url){
let response = yield fetch(url);
return yield response.text();
}
// "Generator" object;
let getFoo = getURL("/foo");
// Prime the pump - run to first yield!
let {value: promise} = getFoo.next();
promise
.then(res => getFoo.next(res).value)
.then(text => console.log(text));
promise .then(res => getFoo.next(res).value) .then(text => console.log(text)) .catch(err => getFoo.throw(error));
async(function* getJSON(url){
let response = yield fetch(url);
let result;
try{
let json = yield response.json();
result = processJson(json);
} catch (err) {
result = attempToRecover(err);
}
return result;
});