Skip to content

Instantly share code, notes, and snippets.

@jchip
Created June 12, 2017 19:26
Show Gist options
  • Save jchip/3029b7de4561fb9ab4437dde8206fa1a to your computer and use it in GitHub Desktop.
Save jchip/3029b7de4561fb9ab4437dde8206fa1a to your computer and use it in GitHub Desktop.

TL;DR Promise tutorial:

  1. Know how to create promise.
  • new Promise( (resolve, reject ) => { })
  • Promise.resolve(<resolved_value>) Where <resolved_value> can be any value, even another promise.
  • Promise.reject(<error_value>)
  1. promise.then( resolved_value => return <x> ) Where <x> either becomes the new resolved_value for next .then or if it's a promise, it becomes the new promise in the chain. Remember to return your promise!

Corollary:

Dealing with error

  1. promise.then( resolved_function, error_function ) or promise.then().catch()
  2. promise.catch( (error) => return <x>) deals with error and returns <x> where <x> becomes the new value or the new promise.
  3. Any function for .then or .catch can throw error.

Start a concurent promise

  1. promise.then( resolved_value => { new Promise( ... ); return <x>; } ) Starts a new promise that's detached from current chain that executes concurrently. Current chain continues with current promise and <x> as the new resolved value.

Now write a simple JS sample that demonstrates each above.

Remember to RETURN Your promise

The most common mistake new promise users make is forgetting to return a promise in the .then function.

Remember, if you don't return your promise, you are starting a new detached promise that executes concurrently. The typical outcome of such error would be, in the sample below:

function another(wait) { 
  return new Promise( resolve => setTimeout( () => {
    console.log("waited", wait);
    resolve("waited");
  }, wait ) )
}

return Promise.resolve(50).then( foo => {
  another(foo);
})
  .then( bar => {
    console.log("result is", bar);
  });

The expected output is:

waited 50
result is waited

But instead you get:

result is undefined
waited 50

That's because the code didn't return the promise from another, making it a detached promise that executes concurrently, and the top promise chain continues to the next .then immediately, with the implicit return value undefined as the new resolved value for bar.

The fix would be to update the line to return another(foo);

Longer Tutorial

Long tutorial https://scotch.io/tutorials/javascript-promises-for-dummies

Typical Unit Test pattern

If you have a unit test that tests a failure case, using Promise:

it("should fail foobar", () => {
  let error;
  return function_that_returns_promise()
    .catch( err => (error = err))
    .then( () => {
      expect(error).to.exist;
    });
});

or

it("should fail foobar", () => {
  return function_that_returns_promise()
    .then( () => {
      throw new Error("expect error");
    }, err => {
      expect(err.message).to.equal("expected message");
    });
});

Async/Await

With the new async/await syntax, Promise becomes much easier and more natural syntatically:

The example from remember to return your promise now look like this, with clean, simpler, and correct code that flows naturally.

function another(wait) { 
  return new Promise( resolve => setTimeout( () => {
    console.log("waited", wait);
    resolve("waited");
  }, wait ) )
}

async function run() {
  const foo = 50;
  const bar = await another(foo);
  console.log("result is", bar);
}

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