I've been playing around with using async and await in my Redux reducers to get rid of all the Promise callback functions - this stuff's like magic!

Note: I'm using Webpack and compiling with the babel-preset-stage-0 for ES2016 await/async.

Before

This is my login function using a Promise and fetch to send data to the API:

export const login = (username, password) => {

  // using thunk middleware since it's async, so return a function
  return dispatch => {

    // create data to send via fetch
    const data = new FormData();
    data.append('username', username);
    data.append('password', password);

    // fire the request
    fetch('http://localhost/login', {
      method: 'POST',
      body: data
    })
      // wait for data back
      .then(response => response.json())

      // response.json() is also async, so wait for that to finish
      .then(data => dispatch(loginSuccess(data)))

      // catch any errors
      .catch(err => dispatch(loginFailure(err)));
  };
};

After

Here's the function now I'm using async/await: I've split it into two functions so the async login request isn't nested. There's also no callback then() functions!

// this just wraps fetch - a simpler 'GET' could just be inline
// note the 'async' keyword
async function loginRequest (username, password) {
  const data = new FormData();
  data.append('username', username);
  data.append('password', password);

  // 'await' the response from fetch - no callback, you can just carry on
  // and use 'response' as normal rather than wrap it in a function!
  const response = await fetch('http://localhost/login', {
    method: 'POST',
    body: data
  });

  // response.json() is async too, but you don't need an 'await'
  // keyword in a return from 'async' (it's implied)
  return response.json();
}

// this is the reducer - no 'async' on the outer function since it just returns a function
export const login = (username, password) => {

  // this one's 'async'
  return async dispatch => {

    // wrap in try to listen for Promise rejections - equivalent of '.catch()'
    try {

      // wait for the fetch to finish then dispatch the result
      const data = await loginRequest(username, password);
      dispatch(loginSuccess(data));
    } catch (e) {

      // catch errors from fetch
      dispatch(loginFailure(e));
    }
  };
};