Skip to content

Instantly share code, notes, and snippets.

@greenlikeorange
Last active October 26, 2020 05:58
Show Gist options
  • Save greenlikeorange/3bcec812582f9e88db01288520280839 to your computer and use it in GitHub Desktop.
Save greenlikeorange/3bcec812582f9e88db01288520280839 to your computer and use it in GitHub Desktop.
Some of my array methods

NOTE: This is my experiment, you can use Rx or something better than mine one XD

At the time, I need an array method act like array.forEach methods I thinking about to create the first function in this gist.

Here I describe example ways to use these functions in code. (I'm so boring to write a story :3)

Exmaple 1: When you to update a list item one by one asynchronously. you may use asyncForEach

async function magicSpell() {
  const birdIds = [1,2,3,4,5,6,7,8,9,10]; // list of items
  
  try {
    await asyncForEach(birdsIds, async (birdId) => {
      await axios.post(`https://shootbirds.com/onebyone/${birdId}`, { hit: true });
    });
    
    console.log('Awesome! let make dinner.');
  } catch (err) {
    console.log('Whoop! All other escape!');
  }
}

Example 2: When you need list of item asynchronously.

async function magicSpell() {
  const cities = 'Yangon Mandalay Pathein'.split(' ');

  const weatherData = await asyncMap(cities, async (cityName) => {
    const { data: weatherStats } = await axios.get(`https://samples.openweathermap.org/data/2.5/weather?q=${cityName}`);
    return weatherStats;
  })
  
  console.log(weatherData) // [weatherStats, weatherStats, weatherStats]
}

Example 3: Or you may want to reduce for combine function

// mock async data retrever
function getPrice(vocherId) {
  const amounts = {
    123: 10000,
    124: 20000,
    125: 30000,
    126: 40000,
  }
  return new Promise((resolve, reject) => {
    return amounts[voucherId] || 0;
  })
}


async function magicSpell() {
  const vouchers = '123 124 125 126'.split(' ');

  const totalPrice = await asyncReduce(vouchers, async (total, voucherId) => {
    return total + await getPrice(voucherId)
  }, 0);
  
  console.log(totalPrice) // 1,000,000
}
/**
* Asynchronous forEach function
* @param {Array|Promise<Array>} array
* @param {AsyncFunction} asyncFn callback
*/
async function asyncForEach(array, asyncFn) {
const resolvedArray = await array; // In case of "array" param is a Promise<Array>
return resolvedArray.reduce(
(monad, currentValue, index, array) => {
return monad.then(async () => {
return asyncFn(currentValue, index, array);
});
},
Promise.resolve(null) // initialValue must be promise
);
}
/**
* Asynchronous map function
* @param {Array|Promise<Array>} array
* @param {AsyncFunction} asyncFn callback
*/
async function asyncMap(array, asyncFn) {
const resolvedArray = await array; // In case of "array" param is a Promise<Array>
return resolvedArray.reduce(
(monad, currentValue, index, array) => {
return monad.then(async (newArray) => {
return newArray.concat(await asyncFn(currentValue, index, array));
});
},
Promise.resolve([]) // initialValue must be promise
);
}
/**
* Asynchronous reduce function
* @param {Array|Promise<Array>} array
* @param {AsyncFunction} asyncFn callback
* @param {Any} initialValue initialValue use in reduce method
*/
async function asyncReduce(array, asyncFn, initialValue) {
const resolvedArray = await array; // In case of "array" param is a Promise<Array>
return resolvedArray.reduce(
(monad, currentValue, index, array) => {
return monad.then(async (accumulator) => {
return asyncFn(accumulator, currentValue, index, array);
});
},
Promise.resolve(initialValue) // initialValue must be promise
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment