empyrealtear 发表于 6 天前

分享一个简易的异步线程池,套娃式异步请求可用

本帖最后由 empyrealtear 于 2025-1-12 21:57 编辑

# 简易异步线程池

## 1. 参考文献

- [如何实现一个简单的并发控制?](https://everfind.github.io/code-reading/async-pool.html)

## 2. 修改后代码

```js
const asyncPool = async (arr, process = (item, arr) => item, begin = (v) => v, end = (v) => v,
    poolLimit = 10, percentComplete = (pct) => pct) => {
    let ret = []
    let executing = new Set()
    let arr_res = new Array(arr.length)
    let completeCount = 0
    // begin
    percentComplete(completeCount / arr.length * 100)
    arr = begin(arr)
    // process
    for (let of arr.entries()) {
      var p = Promise.resolve().then(async () => {
            try {
                let res = await process(item, arr)
                arr_res = res
            } catch (err) {
                console.warn(err)
                arr_res = err
            }
            return
      }).finally(() => {
            percentComplete((++completeCount) / arr.length * 100)
      })
      ret.push(p)
      executing.add(p)
      let clean = () => executing.delete(p)
      p.then(clean).catch(clean)
      if (executing.size >= poolLimit) {
            await Promise.race(executing)
      }
    }
    // end
    return Promise.all(ret).then(() => {
      percentComplete(completeCount / arr.length * 100)
      return end(arr_res)
    })
}
```

## 3. 使用样例

```js
fetch(url).then(async (xhr) => {
    let data = xhr.response?.data
    if (data) {
      return await asyncPool(data, async (v, arr) => {
            let row = {}
            await fetch(v.url).then((xhr2) => {
                let data2 = xhr2.response?.data
                row = { value: data2 }
            })
            return row
      })
    }
})
```
页: [1]
查看完整版本: 分享一个简易的异步线程池,套娃式异步请求可用