DEV Community

Kenny
Kenny

Posted on

ASyncMap

Hi everyone, Today we're going to be working on the toy problem, asyncMap!
This toy problem function has two parameters, an array of asynchronous functions which are (tasks) and a callback. Each of the tasks takes a separate callback and invokes that callback when complete. And the callback being passed into asyncMap is then performed on the results of the callbacks of the tasks. The order of the tasks should be the same as the results

For Example:

asyncMap([
function(cb){
  setTimeout(function(){
    cb('one');
  }, 200);
},
function(cb){
  setTimeout(function(){
    cb('two');
  }, 100);
}
],

function(results){
  // the results array will equal ['one','two'] even though
  // the second function had a shorter timeout.
  console.log(results); // ['one', 'two']
});

Lets break down, this function first we'll need an results array to become our final product to call our callback on, and we'll create a count variable to keep track of our order of tasks by doing so our current function should look like this:

const asyncMap = (tasks, callback) => {
  // create an arr
const results = [];
  // create a count variable to be incremented
  // to keep track our tasks
  let count = 0;
};

Next, we're going to want to iterate through our tasks that are being inputted into our function and each task that is being inputted will become an function that will be that initialized into our results array at each index. As we're doing so, we're going to want to increase our count variable as well for our conditional next.

tasks.forEach((task, i) => {
    // as we're iterating through each task, we'll 
    task(function(result){
      // initialize each result in the results array 
      results[i] = result;
      // increase the count variable for every result in the results array
      count++;
      // create a condition to check if the count is the same
      // as the tasks that are being inputed
      if(count === tasks.length){
        // if so call the callback onto the results array
        // results array should be filled with tasks

in our conditional, we're going to want to check the count is the exact same length as the task that are inputted. and if the conditional passes, we can simply just call our callback onto our results array.

Our final result for the toy problem should look like this:

const asyncMap = (tasks, callback) => {
  // create an arr
const results = [];
  // create a count variable to be incremented
  // to keep track of our tasks
  let count = 0;
  // iterate through the tasks, with the element and index
  tasks.forEach((task, i) => {
    // as we're iterating through each task, we'll 
    task(function(result){
      // initialize each result in the results array 
      results[i] = result;
      // increase the count variable for every result in the results array
      count++;
      // create a condition to check if the count is the same
      // as the tasks that are being inputted
      if(count === tasks.length){
        // if so call the callback onto the results array
        // results array should be filled with tasks
        callback(results);
      }
    });
  });
};

And once you're comfortable with promises we can instead use:

const asyncMap = (tasks, callback) => {
  return Promise.all(tasks.map((task) => new Promise(task))).then(values => callback(values));
};

Thank you for taking the time looking over this blog post! This problem was fun to solve out. I hope it helps those who had troubles with this problem!
Til next time Thank you!

Top comments (0)