Implement mapSeries async function in JavaScript | Frontend Interview question
Hey everyone , I was solving some problems recently and found a very interesting question on Learner's bucket website, btw if you don't know Learner's bucket is very good platform for practicing Javascript problem solving, haha not sponsered :D
So, the question is -
Create a JavaScript function named mapSeries
that functions similarly to the standard Array.map
()
method but is designed for asynchronous operations. Unlike Array.map
()
, which processes elements in parallel, mapSeries
should handle each input sequentially, processing one input at a time.
The mapSeries
function should return a promise. This promise should resolve with an array containing the results of applying an asynchronous iteratee function to each input in the order they were received. If any iteratee invocation results in an error, the promise should reject immediately with this error.
Iteratee Function:
The iteratee is an asynchronous function that takes two arguments:
Input: The current item to be processed.
Callback: A callback function that the iteratee must call once processing is complete.
The callback function should have two parameters:
Error: Should be truthy if an error occurs during the processing of the input, otherwise
null
.Result: The result of processing the input. This should only be considered if the error is
null
.
Behavior:
Inputs should be processed in series; the next input should only be processed once the current one has been fully handled.
If the iteratee calls the callback with an error,
mapSeries
should immediately reject the promise with this error and cease processing further inputs.If all inputs are processed without errors,
mapSeries
should resolve with an array of results corresponding to the inputs.
I hope you got the idea what question is asking to do, I am going to solve it using recursion , though it's can be solved in many ways and on learner's bucket website it's solved using array.reduce method but after going through that solution i felt it was bit confusing, that's why I am using recursion.
So here we go
// First of all create a function with any name you want
// this function should take two params , array and iteratee fn
function mapSeries (input, iteratee){
// do as the question says, it should return a promise.
return new Promise((resolve, reject) => {
// a variable to store all the values,
const final = [];
// a variable to track where we are in the loop of input
let index = 0;
// this function is to call the iteratee fn depending
// on the condition
function processNext(){
// if index less than input length that means
// all inputs are not yet passed to iteratee ,.. easy ?
if(index < input.length){
iteratee(input[index], ((err, result) => {
// as the question suggest that iteratee fn takes input
// and a callback with params err and result
// if its err check and reject
if(err){
reject(err)
}else {
// storing the value returned by iteratee fn
final.push(result)
index++
// calling the function itself, it will fail after
// after all the input is processed
processNext()
}
}))
}else {
// resolving if every input is processed
resolve(final)
}
}
// invoking processNext fn
processNext()
})
}
Test
let numPromise = mapSeries([1, 2, 3, 4, 5], function (num, callback) {
setTimeout(function () {
num = num * 2;
console.log(num);
// throw error
if(num === 12){
callback(true);
}else{
callback(null, num);
}
}, 2000);
});
numPromise
.then((result) => console.log("success:" + result))
.catch(() => console.log("no success"));
Output:
// each number will be printed after a delay of 2 seconds
2
4
6
8
10
"success:2,4,6,8,10" // this will be printed immediately after last
Subscribe to my newsletter
Read articles from Aditya Singh directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Aditya Singh
Aditya Singh
Hi there! I'm a frontend developer with a passion for creating beautiful and intuitive user interfaces. I love being able to combine my creative side with my technical skills to bring unique ideas to life. When I'm not coding, you can usually find me behind the lens of my camera, exploring the world of photography. I believe that creativity is an essential part of both my personal and professional life, and I'm constantly striving to find new ways to express it.