pForEach

pForEach

  • (fn: AsyncFunction) => async (collection: Collection) => Collection
  1. Call an async function for each entry.

    The function is called for all entries at once. See Notes for an example.

    const log = async n => console.log('n: ' + n)
    const logAll = pForEach(log)
    
    await logAll([1, 2, 3])
    // prints
    // n: 1
    // n: 2
    // n: 3
    const log = async (n: number) => console.log('n: ' + n)
    const logAll = pForEach(log)
    
    await logAll([1, 2, 3])
    // prints
    // n: 1
    // n: 2
    // n: 3
    
    const log = async n => console.log('n: ' + n)
    const logAll = pForEach(log)
    
    await logAll([1, 2, 3])
    // prints
    // n: 1
    // n: 2
    // n: 3
    const log = async (n: number) =>
      console.log('n: ' + n)
    const logAll = pForEach(log)
    
    await logAll([1, 2, 3])
    // prints
    // n: 1
    // n: 2
    // n: 3
    
  2. Sometimes we want to call an async function for each entry in a collection. Below, we want to track the items in our customer's cart. Let's call our mock store API to track each item.

    const mockStoreApi = {
      trackCartItem: async ({ item, user }) => {
        console.log(`item '${item}' is in ${user}'s cart`)
      },
    }
    
    const currentUser = 'luke'
    const shoppingCart = ['broom', 'mop', 'detergent']
    const trackAllCartItems = pForEach(mockStoreApi.trackCartItem)
    const itemUserArgs = shoppingCart.map(item => ({ item, user: currentUser }))
    await trackAllCartItems(itemUserArgs)
    type ItemUser = {
      item: string
      user: string
    }
    
    const mockStoreApi = {
      trackCartItem: async ({ item, user }: ItemUser) => {
        console.log(`item '${item}' is in ${user}'s cart`)
      },
    }
    
    const currentUser = 'luke'
    const shoppingCart = ['broom', 'mop', 'detergent']
    const trackAllCartItems = pForEach(mockStoreApi.trackCartItem)<ItemUser[]>
    const itemUserArgs = shoppingCart.map(item => ({ item, user: currentUser }))
    await trackAllCartItems(itemUserArgs)
    
    const mockStoreApi = {
      trackCartItem: async ({ item, user }) => {
        console.log(
          `item '${item}' is in ${user}'s cart`
        )
      },
    }
    
    const currentUser = 'luke'
    const shoppingCart = ['broom', 'mop', 'detergent']
    const trackAllCartItems = pForEach(
      mockStoreApi.trackCartItem
    )
    const itemUserArgs = shoppingCart.map(item => ({
      item,
      user: currentUser,
    }))
    await trackAllCartItems(itemUserArgs)
    type ItemUser = {
      item: string
      user: string
    }
    
    const mockStoreApi = {
      trackCartItem: async ({
        item,
        user,
      }: ItemUser) => {
        console.log(
          `item '${item}' is in ${user}'s cart`
        )
      },
    }
    
    const currentUser = 'luke'
    const shoppingCart = ['broom', 'mop', 'detergent']
    const trackAllCartItems = pForEach(
      mockStoreApi.trackCartItem
    )<ItemUser[]>
    const itemUserArgs = shoppingCart.map(item => ({
      item,
      user: currentUser,
    }))
    await trackAllCartItems(itemUserArgs)
    
  3. pForEach calls the function for all entries at once. See async.eachOfLimit if you want to limit the concurrency.

    const start = new Date().getTime()
    
    const logMsPassed = async n => {
      const msPassed = Date.now() - start
      console.log(`ms passed: ${msPassed}, for n = ${n}`)
    
      await pWaitMs(20)
    }
    const logMsPassedForAll = pForEach(logMsPassed)
    
    await logMsPassedForAll([1, 2, 3])
    const totalMsPassed = Date.now() - start
    console.log(`total ms passed: ${totalMsPassed}`)
    const start = new Date().getTime()
    
    const logMsPassed = async (n: number) => {
      const msPassed = Date.now() - start
      console.log(`ms passed: ${msPassed}, for n = ${n}`)
    
      await pWaitMs(20)
    }
    const logMsPassedForAll = pForEach(logMsPassed)<number[]>
    
    await logMsPassedForAll([1, 2, 3])
    const totalMsPassed = Date.now() - start
    console.log(`total ms passed: ${totalMsPassed}`)
    
    const start = new Date().getTime()
    
    const logMsPassed = async n => {
      const msPassed = Date.now() - start
      console.log(
        `ms passed: ${msPassed}, for n = ${n}`
      )
    
      await pWaitMs(20)
    }
    const logMsPassedForAll = pForEach(logMsPassed)
    
    await logMsPassedForAll([1, 2, 3])
    const totalMsPassed = Date.now() - start
    console.log(`total ms passed: ${totalMsPassed}`)
    const start = new Date().getTime()
    
    const logMsPassed = async (n: number) => {
      const msPassed = Date.now() - start
      console.log(
        `ms passed: ${msPassed}, for n = ${n}`
      )
    
      await pWaitMs(20)
    }
    const logMsPassedForAll = pForEach(logMsPassed)<
      number[]
    >
    
    await logMsPassedForAll([1, 2, 3])
    const totalMsPassed = Date.now() - start
    console.log(`total ms passed: ${totalMsPassed}`)