Prray —— 如果数组支持异步函数,有时候代码写起来会更自然
之前看到一篇国外博客,博主花了很大力气“抱怨” JS 原生数组对异步函数不友好:
// 比如你不能这么写代码
const resps = await urls.map(request)
// 而是只能
const resps = await Promise.all(urls.map(request))
这还只是写法上的差异,在实际开发中,并发往往还需要限速,然而JS 原生上并没有提供简单易用的方法,只能借助社区的三方实现。
我们总是借助 bluebird 这个三方 Promise 实现来拟补数组的不足(比如使用 bluebird.map
),却忽略了一个想法:如果数组能够对异步函数更加友好,代码是不是能写的更加自然一些?
// 比如可以这么写代码:
const json = await urls.mapAsync(fetch).mapAsync(r => r.json())
// 或者考虑并发限速
const json = await urls.mapAsync(fetch, { concurrency: 10 }).mapAsync(r => r.json())
// 同时能和普通方法正常地**链状调用**
await files.filterAsync(isExisted).concat(others).forEach(remove)
这个库 prray 就在尝试这个想法。它的原理是在原生 Array 的基础上进行拓展,在兼容数组的前提下,让你可以像上面那样写代码。
import { prray } from 'prray'
const urls = prray(['www.google.com', 'npmjs.org'])
const htmls = await urls.mapAsync(fetch, { concurrency: 10 }).mapAsync(r => r.text())
那么,和原生数组有多兼容呢?prray 的目标是:用起来就和原生数组一摸一样
import { prray } from 'prray'
const urls = prray(['www.google.com', 'npmjs.org'])
console.log(urls.length) // 2
console.log(urls[0]) // www.google.com
console.log(...urls) // www.google.com, npmjs.org
console.log(Array.isArray(urls)) // true
console.log(JSON.stringify(urls)) // ['www.google.com', 'npmjs.org']
for (const url of urls) {
console.log(url)
}
// www.google.com
// npmjs.org
所以在一些合适的场合,你甚至可以用 Prray 代替原生的数组。
如果你对这个项目感兴趣,或者质疑兼容情况、项目质量,可以前往仓库,相信不会让你特别失望:https://github.com/Bin-Huang/prray
谢谢你看完,欢迎讨论