DEV Community

Discussion on: How to rewrite a callback function in Promise form and async/await form in JavaScript

Collapse
 
rifi2k profile image
Reilly Lowery

Real example and also I would simplify the error handling a ton and lose the try catch.

/**
 * Async Await Error Handling
 *
 * Example:
 *  const [err, response] = await to(
 *    axios.get(url)
 *  );
 * if (err) throw new Error('u broke it');
 * const hi = response.hi;
 *
 * @module to
 */

export default (promise) =>
  promise.then((data) => [null, data]).catch((err) => [err]);

You can pass anything that returns a promise to that module like so.

So here we are using the WP backbone api to return a collection of whatever and checking if more exist each time, when its all done we are combining them all together and loading the result into the data variable so we can stop our loading event on the table and show all the results. The js api will only return 100 items in a collection at a time and in this case we needed to grab 200-300 of whatever and load the table with all the data so the searching and sorting is instant so we sacrifice the inital time to grab all the data from better UI once we do.

PS: This is the basic layout of a Vue component, I just left off the methods wrapper around the loadItems function so you could see it easier.

import to from './to';

export default {

  data() {
    return {
      tableLoading: false,
      allTasks: []
    };
  },

  async loadItems() {

    // Start loading.
    this.tableLoading = true;

    // All our things will be put here.
    let all = [];

    // Get the collection of tasks.
    const tasksCollection = new wp.api.collections.Task();

    // Now we can use our to module for error handling.
    // collection.fetch could be axios or whatever returning a promise.
    const [err, response] = await to(
      tasksCollection.fetch({
        data: { per_page: 100 }
      })
    );
    if (err) throw new Error('Failed to load task collection');

    // We have lodashES in our app already so union() is available here.
    all = union(all, response);

    // This is checking if more exist, but it could be anything
    // your flow was dependant on.
    const hasMore = () => tasksCollection.hasMore();

    // Looping through another chunk.
    const loopMore = async () => {
      if (hasMore()) {
        const [errMore, responseMore] = await to(tasksCollection.more());
        if (errMore) throw new Error('Failed to load task collection');
        all = union(all, responseMore);
        loopMore();
      } else {
        // No more we are done, up yonder in the file we are
        // waiting for allTasks to be set to do other things.
        this.allTasks = all;
      }
    };

    loopMore();
  },

}

With async await and your example you described you would basically have a method or function returning a promise for checking on if the file exists and reading the data from it, probably using axios or fetch. Then another method returning a promise to create and write to a file. Each method would return a response and you would await on the result before doing the next part.

Hope this gave you a real world example to see how this stuff can be used.