pFind
pFind
(predicate: AsyncPredicate) => async (collection: Collection) => Value | undefined
One at a time, asynchronously find the first value that passes a condition
const gt2 = async n => n > 2 const findGt2 = pFind(gt2) await findGt2([1, 2, 3]) // is 3 await findGt2([1, 2]) // is undefined
const gt2 = async (n: number) => n > 2 const findGt2 = pFind(gt2) await findGt2([1, 2, 3]) // is 3 await findGt2([1, 2]) // is undefined
const gt2 = async n => n > 2 const findGt2 = pFind(gt2) await findGt2([1, 2, 3]) // is 3 await findGt2([1, 2]) // is undefined
const gt2 = async (n: number) => n > 2 const findGt2 = pFind(gt2) await findGt2([1, 2, 3]) // is 3 await findGt2([1, 2]) // is undefined
Sometimes we want to asynchronously find a value that passes a condition. Below, we're running an online store. Customers have expressed confusion about discount codes being applied. Let's clarify by showing which item qualifies their order for a code.
const mockStoreApi = { qualifiesForDiscount: async ({ code, item }) => item === 'detergent' && code === 'soft', } const shoppingCart = ['broom', 'mop', 'detergent'] const findQualifyingItem = pFind(mockStoreApi.qualifiesForDiscount) const itemCodeArgs = shoppingCart.map(item => ({ item, code: 'soft' })) const result = await findQualifyingItem(itemCodeArgs) if (result) { const { code, item } = result console.log(`code '${code}' applied because you bought ${item}`) }
type ItemCode = { item: string code: string } const mockStoreApi = { qualifiesForDiscount: async ({ code, item }: ItemCode) => item === 'detergent' && code === 'soft', } const shoppingCart = ['broom', 'mop', 'detergent'] const findQualifyingItem = pFind(mockStoreApi.qualifiesForDiscount)<ItemCode[]> const itemCodeArgs = shoppingCart.map(item => ({ item, code: 'soft' })) const result = await findQualifyingItem(itemCodeArgs) if (result) { const { code, item } = result console.log(`code '${code}' applied because you bought ${item}`) }
const mockStoreApi = { qualifiesForDiscount: async ({ code, item }) => item === 'detergent' && code === 'soft', } const shoppingCart = ['broom', 'mop', 'detergent'] const findQualifyingItem = pFind( mockStoreApi.qualifiesForDiscount ) const itemCodeArgs = shoppingCart.map(item => ({ item, code: 'soft', })) const result = await findQualifyingItem(itemCodeArgs) if (result) { const { code, item } = result console.log( `code '${code}' applied because you bought ${item}` ) }
type ItemCode = { item: string code: string } const mockStoreApi = { qualifiesForDiscount: async ({ code, item, }: ItemCode) => item === 'detergent' && code === 'soft', } const shoppingCart = ['broom', 'mop', 'detergent'] const findQualifyingItem = pFind( mockStoreApi.qualifiesForDiscount )<ItemCode[]> const itemCodeArgs = shoppingCart.map(item => ({ item, code: 'soft', })) const result = await findQualifyingItem(itemCodeArgs) if (result) { const { code, item } = result console.log( `code '${code}' applied because you bought ${item}` ) }
pFind awaits each item before moving onto the next. See
async.detectLimit
if you want to run more than one call at a time.const start = new Date().getTime() const gt2 = async n => { const msPassed = Date.now() - start console.log(`ms passed: ${msPassed}, for n = ${n}`) await pWaitMs(20) return n > 2 } const findGt2 = pFind(gt2) await findGt2([1, 2, 3]) const totalMsPassed = Date.now() - start console.log(`total ms passed: ${totalMsPassed}`)
const start = new Date().getTime() const gt2 = async (n: number) => { const msPassed = Date.now() - start console.log(`ms passed: ${msPassed}, for n = ${n}`) await pWaitMs(20) return n > 2 } const findGt2 = pFind(gt2)<number[]> await findGt2([1, 2, 3]) const totalMsPassed = Date.now() - start console.log(`total ms passed: ${totalMsPassed}`)
const start = new Date().getTime() const gt2 = async n => { const msPassed = Date.now() - start console.log( `ms passed: ${msPassed}, for n = ${n}` ) await pWaitMs(20) return n > 2 } const findGt2 = pFind(gt2) await findGt2([1, 2, 3]) const totalMsPassed = Date.now() - start console.log(`total ms passed: ${totalMsPassed}`)
const start = new Date().getTime() const gt2 = async (n: number) => { const msPassed = Date.now() - start console.log( `ms passed: ${msPassed}, for n = ${n}` ) await pWaitMs(20) return n > 2 } const findGt2 = pFind(gt2)<number[]> await findGt2([1, 2, 3]) const totalMsPassed = Date.now() - start console.log(`total ms passed: ${totalMsPassed}`)