javascript - Typescript/ES7 中异步/等待的有限并行性

标签 javascript typescript async-await

我一直在尝试使用 Typescript,但我现在对如何有效使用 async/await 有点困惑。

我正在向数据库中插入一堆记录,我需要获取每次插入返回的 ID 列表。下面的简化示例一般有效,但它并不像我想要的那样优雅,而且它完全是顺序的。

async function generatePersons() {
    const names = generateNames(firstNames, lastNames);
    let ids = []
    for (let name of names) {
        const id = await db("persons").insert({
            first_name: name.firstName,
            last_name: name.lastName,
        }).returning('id');
        ids.push(id[0])
    }
    return ids
}

我尝试使用 map 来避免手动创建 ids 列表,但我可以让它工作。

我还想拥有有限数量的并行性。所以我的异步调用应该在一定限度内并行发生,例如我只希望有 10 个开放请求,但不会更多。

在 Typescript 或 Javascript ES7 中,是否有一种相当优雅的方法可以通过 async/await 实现这种有限的并行性?还是我试图让这个功能做一些它不打算做的事情?

PS:我知道有针对数据库的批量插入方法,这个例子有点人为,因为我可以使用它们来解决这个特定问题。但这让我想知道一般情况下我没有可用的预定义批量方法,例如有网络请求

最佳答案

Psst, there's a package that does this for you on npm called p-map


Promise.all 将允许您等待所有请求停止完成,而不会阻止它们的创建。

但是,它确实听起来像您有时想要阻止。具体来说,听起来您想在任何给定时间限制飞行中的请求数量。这是我突然想到的东西(但还没有完全测试!)

async function asyncThrottledMap<T, U>(maxCount: number, array: T[], f: (x: T) => Promise<U>) {
    let inFlight = new Set<Promise<U>>();
    const result: Promise<U>[] = [];

    // Sequentially add a Promise for each operation.
    for (let elem of array) {

        // Wait for any one of the promises to complete if there are too many running.
        if (inFlight.size >= maxCount) {
            await Promise.race(inFlight);
        }

        // This is the Promise that the user originally passed us back.
        const origPromise = f(elem);
        // This is a Promise that adds/removes from the set of in-flight promises.
        const handledPromise = wrap(origPromise);
        result.push(handledPromise);
    }

    return Promise.all(result);

    async function wrap(p: Promise<U>) {
        inFlight.add(p);
        const result = await p;
        inFlight.delete(p);
        return result;
    }
}

上面,inFlight 是一组当前正在进行的操作。

result 是一个由包装 Promise 组成的数组。这些包装的 promise 中的每一个基本上都在 inFlight 操作集中添加或删除操作。如果进行中的操作太多,那么这将使用 Promise.race 来完成任何一个进行中的操作。

希望对您有所帮助。

关于javascript - Typescript/ES7 中异步/等待的有限并行性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39195441/

相关文章:

Typescript - 获取接口(interface)的所有实现

c# - 异步和等待 - 控制台、Windows 窗体和 ASP.NET 之间的区别

javascript - 等待/异步问题

Django HTML 模板中的 Javascript 变量

javascript - Google 堆叠条形图,x 为日期,y 为时间

javascript - 使用 JavaScript 计算数组内的总和

node.js - 如何在 Typescript 项目中使用来自 Node 16 的计时器/ promise ?

html - 使用 typeScript 滚动到我的 webView 上的 x,y 坐标

c# - async-await 的不同行为

javascript - 根据其邻居更改表格单元格颜色