This solution is generated by ChatGPT, correctness is not guaranteed.

AI solution for JavaScript Coding Question on BFE.dev
30. implement async helper - `parallel()`

Solution

This problem can be solved by keeping track of how many async functions have completed and their results. When all of the async functions complete or an error occurs, the final callback can be triggered with the results or error.

Here is the implementation of parallel():

function parallel(asyncFuncs) {
  return function(callback, data) {
    let completed = 0 // number of async functions completed
    let results = [] // results from completed async functions
    
    // iterate through asyncFuncs and call each one with a callback
    asyncFuncs.forEach((asyncFunc, index) => {
      asyncFunc((error, result) => {
        // if error has occurred, immediately trigger the final callback with the error
        if (error) {
          callback(error, null)
          return
        }
        
        // store the result from the completed async function
        results[index] = result
        completed++
        
        // if all async functions have completed, trigger the final callback with the results
        if (completed === asyncFuncs.length) {
          callback(null, results)
        }
      }, data)
    })
  }
}

The parallel() function accepts an array of AsyncFuncs, and returns a new function which accepts a final callback and a data parameter to be passed to each AsyncFunc. Within the returned function, the completed counter keeps track of how many async functions have completed, and the results array stores the results from each completed function in their respective indices. The forEach loop then iterates through the asyncFuncs array, calling each one with a callback that either triggers the final callback with an error or updates the completed counter and results array. Once all async functions have completed, the completed counter will equal the length of the asyncFuncs array, and the final callback is triggered with the results array.

Here is an example of using parallel():

// example async functions
const async1 = (callback) => {
  setTimeout(() => {
    callback(null, 1)
  }, 1000)
}

const async2 = (callback) => {
  setTimeout(() => {
    callback(null, 2)
  }, 2000)
}

const async3 = (callback) => {
  setTimeout(() => {
    callback(null, 3)
  }, 1500)
}

// using parallel() with async functions
const all = parallel([async1, async2, async3])

all((error, data) => {
  if (error) {
    console.log(error)
  } else {
    console.log(data) // [1, 2, 3]
  }
}, null)

In this example, the async1, async2, and async3 functions are defined as setTimeout calls that resolve with 1, 2, and 3 respectively after a certain amount of time. The all variable is then defined as the result of calling parallel() with an array of the three async functions. Finally, the all() function is called with a final callback that logs the error or results to the console, and a null data parameter. When the all() function completes, it logs [1, 2, 3] to the console.