Skip to content

Instantly share code, notes, and snippets.

@sangkukbae12
Created May 14, 2020 00:55
Show Gist options
  • Save sangkukbae12/23e6773ed029319254ae29308043fbf8 to your computer and use it in GitHub Desktop.
Save sangkukbae12/23e6773ed029319254ae29308043fbf8 to your computer and use it in GitHub Desktop.
JavaScript Promises in Depth
// 1. Create a Promise Chain in JavaScript with Promise.prototype.then()
const API_URL = "https://starwars.egghead.training/";
const output = document.getElementById("output");
function getFilmTitles(films) {
return films
.slice()
.sort((a, b) => a.episode_id - b.episode_id)
.map(film => `${film.episode_id}. ${film.title}`)
.join("\n");
}
output.innerText = "Loading ...";
fetch(API_URL + "films")
.then(response => response.json())
.then(films => {
output.innerText = getFilmTitles(films);
});
// 2. Catch Errors in a JavaScript Promise Chain with Promise.prototype.catch()
const API_URL = "https://starwars.egghead.training/";
const output = document.getElementById("output");
function getFilmTitles(films) {
return films
.slice()
.sort((a, b) => a.episode_id - b.episode_id)
.map(film => `${film.episode_id}. ${film.title}`)
.join("\n");
}
output.innerText = "Loading ...";
// fetch(API_URL + "films")
fetch(API_URL + "movies")
.then(response => {
if (!response.ok) {
throw Error("Unsuccessful response");
}
return response.json().then(films => {
output.innerText = getFilmTitles(films);
});
})
.catch(error => {
console.warn(error);
output.innerText = ":(";
});
// 3. Execute Cleanup Logic in a JavaScript Promise Chain with Promise.prototype.finally()
const API_URL = "https://starwars.egghead.training/";
const output = document.getElementById("output");
const spinner = document.getElementById("spinner");
function getFilmTitles(films) {
return films
.slice()
.sort((a, b) => a.episode_id - b.episode_id)
.map(film => `${film.episode_id}. ${film.title}`)
.join("\n");
}
fetch(API_URL + "films")
.then(response => {
if (!response.ok) {
throw new Error("Unsuccessful response");
}
return response.json().then(films => {
output.innerText = getFilmTitles(films);
});
})
.catch(error => {
console.warn(error);
output.innerText = ":(";
})
.finally(() => {
spinner.remove();
});
// 4. Create a Rejected Promise in JavaScript with Promise.reject()
const API_URL = "https://starwars.egghead.training/";
const output = document.getElementById("output");
const spinner = document.getElementById("spinner");
function getFilmTitles(films) {
return films
.slice()
.sort((a, b) => a.episode_id - b.episode_id)
.map(film => `${film.episode_id}. ${film.title}`)
.join("\n");
}
// fetch(API_URL + "films")
fetch(API_URL + "movies")
.then(response => {
if (!response.ok) {
return Promise.reject(
new Error("Unsuccessful response")
);
}
return response.json().then(films => {
output.innerText = getFilmTitles(films);
});
})
.catch(error => {
console.warn(error);
output.innerText = ":(";
})
.finally(() => {
spinner.remove();
});
// 5. Create a Resolved Promise in JavaScript with Promise.resolve()
// Required to make jQuery work within CodeSandbox
const $ = window.jQuery || require("jquery");
const API_URL = "https://starwars.egghead.training/";
const output = document.getElementById("output");
const spinner = document.getElementById("spinner");
function getFilmTitles(films) {
return films
.slice()
.sort((a, b) => a.episode_id - b.episode_id)
.map(film => `${film.episode_id}. ${film.title}`)
.join("\n");
}
Promise.resolve($.ajax(API_URL + "films"))
.then(films => {
output.innerText = getFilmTitles(films);
})
.catch(error => {
console.warn(error);
output.innerText = ":(";
})
.finally(() => {
spinner.remove();
});
// 6. Create a New Promise in JavaScript with the Promise Constructor
function sleep(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}
console.log("Right away");
sleep(1000)
.then(() => {
console.log("After 1s");
})
.then(() => sleep(1000))
.then(() => {
console.log("After 2s");
})
.catch(() => {
console.log("Rejected");
});
// 7. Convert a Callback-Based JavaScript Function to a Promise-Based One
const fs = require("fs");
const util = require("util");
const readFile = util.promisify(fs.readFile);
readFile(__filename, "utf8").then(
contents => {
console.log(contents);
},
error => {
console.error(error);
}
);
/*
function readFile(path, encoding) {
return new Promise((resolve, reject) => {
fs.readFile(path, encoding, (error, contents) => {
if (error) {
reject(error);
} else {
resolve(contents);
}
});
});
}
*/
// 8. Wait for the Fastest JavaScript Promise to Settle with Promise.race()
function resolveAfter(ms, value) {
return new Promise(resolve => {
setTimeout(() => {
resolve(value);
}, ms);
});
}
function timeout(ms, promise) {
let timeoutID;
const timeoutPromise = new Promise((_, reject) => {
timeoutID = setTimeout(() => {
reject(
new Error(`Operation timed out after ${ms}ms`)
);
}, ms);
});
return Promise.race([promise, timeoutPromise]).finally(
() => {
clearTimeout(timeoutID);
}
);
}
const promise = resolveAfter(1000, "A");
timeout(500, promise).then(
value => {
console.log(`Fulfilled: ${value}`);
},
error => {
console.log(`Rejected: ${error}`);
}
);
// 9. Wait for Multiple JavaScript Promises to Be Fulfilled with Promise.all()
const API_URL = "https://starwars.egghead.training/";
const output = document.getElementById("output");
const spinner = document.getElementById("spinner");
function queryAPI(endpoint) {
return fetch(API_URL + endpoint).then(response => {
return response.ok
? response.json()
: Promise.reject(Error("Unsuccessful response"));
});
}
Promise.all([
queryAPI("films"),
queryAPI("planets"),
queryAPI("species")
])
.then(([films, planets, species]) => {
output.innerText =
`${films.length} films, ` +
`${planets.length} planets, ` +
`${species.length} species`;
})
.catch(error => {
console.warn(error);
output.innerText = ":(";
})
.finally(() => {
spinner.remove();
});
// 10. Wait for Multiple JavaScript Promises to Settle with Promise.allSettled()
const API_URL = "https://starwars.egghead.training/";
const output = document.getElementById("output");
const spinner = document.getElementById("spinner");
function queryAPI(endpoint) {
return fetch(API_URL + endpoint).then(response => {
return response.ok
? response.json()
: Promise.reject(Error("Unsuccessful response"));
});
}
Promise.allSettled([
queryAPI("films").then(f => `${f.length} films`),
queryAPI("planets").then(p => `${p.length} planets`),
queryAPI("species").then(s => `${s.length} species`),
queryAPI("vehicles").then(v => `${v.length} vehicles`)
])
.then(results => {
const statistics = results
.filter(result => result.status === "fulfilled")
.map(result => result.value);
output.innerText =
statistics.length === 0
? "Failed to load statistics :("
: statistics.join("\n");
})
.catch(error => {
console.warn(error);
output.innerText = ":(";
})
.finally(() => {
spinner.remove();
// 11. Wait for the Fastest JavaScript Promise to Be Fulfilled with Promise.any()
const API_URL_1 = "https://starwars.egghead.training/";
const API_URL_2 = "https://swapi.mariusschulz.com/";
const output = document.getElementById("output");
const spinner = document.getElementById("spinner");
function query(rootURL, endpoint) {
return fetch(rootURL + endpoint).then(response => {
return response.ok
? response.json()
: Promise.reject(Error("Unsuccessful response"));
});
}
function queryAPI(endpoint) {
return Promise.any([
query(API_URL_1, endpoint),
query(API_URL_2, endpoint)
]).catch(() => {
return Promise.reject(
Error(`Failed to fetch endpoint "${endpoint}"`)
);
});
}
function getFilmTitles(films) {
return films
.slice()
.sort((a, b) => a.episode_id - b.episode_id)
.map(film => `${film.episode_id}. ${film.title}`)
.join("\n");
}
queryAPI("films")
.then(films => {
output.innerText = getFilmTitles(films);
})
.catch(error => {
console.warn(error);
output.innerText = ":(";
})
.finally(() => {
spinner.remove();
});
// 12. Await a JavaScript Promise in an async Function with the await Operator
const API_URL = "https://starwars.egghead.training/";
const output = document.getElementById("output");
const spinner = document.getElementById("spinner");
async function queryAPI(endpoint) {
const response = await fetch(API_URL + endpoint);
if (response.ok) {
return response.json();
}
throw Error("Unsuccessful response");
}
async function main() {
try {
const [films, planets, species] = await Promise.all([
queryAPI("films"),
queryAPI("planets"),
queryAPI("species")
]);
output.innerText =
`${films.length} films, ` +
`${planets.length} planets, ` +
`${species.length} species`;
} catch (error) {
console.warn(error);
output.innerText = ":(";
} finally {
spinner.remove();
}
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment