Skip to content

Instantly share code, notes, and snippets.

@MadaraUchiha
Created December 24, 2015 10:08
Show Gist options
  • Select an option

  • Save MadaraUchiha/338f7ac8269ecc0d44e0 to your computer and use it in GitHub Desktop.

Select an option

Save MadaraUchiha/338f7ac8269ecc0d44e0 to your computer and use it in GitHub Desktop.
Implement the Promise constructor challenge

Task 1

A Promise is an object that represents a (potential value) over time. A replacement for callbacks. Your job is to implement the Promise object. Here are the requirements:

  • The Promise constructor takes a function with two arguments: new Promise((resolve, reject) => { ... })
    • Calling the resolve function inside of the handler will resolve the promise (i.e. success). You can call resolve with a single argument, which will be passed to .then().
    • Calling the reject function will reject it (i.e. error). You should always call reject with an Error instance, which will be passed to .then().
  • A Promise has three states, it starts at "pending" and can mutate only once to either "resolved" or "rejected".
  • A Promise object has a .then() method which accepts two functions, the first will call if it's resolved, and the second if it rejects.

Example:

const delay = (time) => new Promise((resolve, reject) => 
setTimeout(() => Math.random() > 0.5 ? resolve : reject(new Error("bad luck")), time));
let promise = delay(500);
promise.then(() => console.log("Success!"), (err) => console.error(`Whoops! ${err.message}`)); // After half a second, will either log "Success!" or "Whoops! bad luck".

Goal: Implement the Promise constructor. (You should use a different name than Promise, MyPromise or something)

Task 2:

Using the Promise constructor for everything is verbose. The following helper static methods are useful: Promise.resolve(value) - Returns a Promise which immediately resolves with the value. Promise.reject(error) - Returns a Promise which immediately rejects with the error.

Goal: Implement the Promise.resolve() and Promise.reject() static methods.

Task 3:

One of the most useful features of Promises is that you can return from the .then() handler. Returning a value from the .then() handler will make the .then() handler to return a Promise which immediately resolves to that value. Returning a Promise from the .then() handler will return a new Promise which waits for that Promise to resolve. So

const delay  = (time) => new Promise((resolve) => setTimeout(resolve, time));
delay(100)
.then(() => 42) // Note: () => 42 is equivalent to function() { return 42; }
.then((value) => console.log(value)); // 42

delay(100)
.then(() => delay(200))
.then(() => console.log('Done!')); // Waits for 300ms

Goal: Implement the ability to return values and Promises from the .then() handler, and chain .then()s.

Task 4:

While a Promise is very useful on its own, its true usefulness comes from aggregation.

The Promise constructor comes with 2 very useful static methods:Promise.all() and Promise.race()

Promise.all() accepts an array of Promise objects, and returns a Promise which resolves when all of the Promises in the array resolve. The resolution value is an array of the individual values of the Promises in the original array, in the order in which they were in the array. So:

Promise.all([Promise.resolve(1), Promise.resolve(2), Promise.resolve(2)]).then((results) => console.log(results)); // Logs [1, 2, 3]

Promise.race() accepts an array of Promise objects, and returns a new Promise which waits for the first Promise to resolve/reject (and then resolves/reject with the same value/error). So:

let p1 = delay(500);
let p2 = delay(100);
let p3 = delay(400);
Promise.race([p1, p2 p3]); // === p2 (when p2 resolves).

Goal: Implement Promise.all() and Promise.race()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment