Prray —— 如果数组支持异步函数,有时候代码写起来会更自然
发布于 5 年前 作者 Bin-Huang 3742 次浏览 来自 分享

之前看到一篇国外博客,博主花了很大力气“抱怨” 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

  • 与原生 Array 保持兼容(非常多的测试
  • 添加了各种异步版本的方法
  • 即使是异步方法,也可以链状调用
  • 支持限速
  • 测试良好
  • 没有其他依赖
  • 完善的 TS 类型

谢谢你看完,欢迎讨论

回到顶部