当前位置: 首页 > 知识库问答 >
问题:

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

金嘉
2023-03-14

我一直在尝试打字稿,但我现在有点卡在如何有效地使用async/wait上。

我正在向数据库中插入一组记录,我需要获得每次插入返回的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?或者我试图让这个html" target="_blank">功能做一些它不打算做的事情?

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

共有3个答案

鲁鸿
2023-03-14

有没有一种合理优雅的方法来实现这种有限的并行性与异步/等待在TypeScript或Javascript ES7

你必须使用Promise。全部。i、 e.收集数组中的所有promise并等待promise。全部([all,the,stuff])

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

慕容星晖
2023-03-14

检查异步并行库,它提供了各种帮助函数,使执行并行操作变得容易。使用这个库,您的代码可以看起来像这样...

async function generatePersons(): Promise<number[]> {
    const names = generateNames(firstNames, lastNames);
    return await Parallel.map(names, async (name) => 
        await db("persons").insert({
            first_name: name.firstName,
            last_name: name.lastName,
        }).returning('id'));
}

如果你想将实例的数量限制在一次四个,你可以简单地执行以下操作。。。

Parallel.concurrency = 4;
祁鸿哲
2023-03-14

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是当前正在执行的一组操作。

结果是打包的Promises的数组。每个打包的promise基本上都是添加或删除inFlight操作集合中的操作。如果有太多的运行中操作,那么这将使用Promise.race来完成任何一个运行中操作。

希望这有所帮助。

 类似资料:
  • 问题内容: 据我了解,在ES7 /ES2016中,将多个in放在代码中的工作方式类似于带有promise的链接,这意味着它们将一个接一个地执行而不是并行执行。因此,例如,我们有以下代码: 我是否正确理解仅在完成时才会调用?并行调用它们的最优雅方式是什么? 我想在Node中使用它,所以也许有一个异步库解决方案? 编辑:我对这个问题提供的解决方案不满意:减速是由于异步生成器中非并行等待Promise的

  • 我试图在react/electron项目中使用async/await,但它不起作用。我想要的是获取docker容器状态列表。但是安慰。日志(列表)返回未定义的。 有人能帮我吗?:)

  • 我正在尝试将数据库调用移出控制器,以清理并使其可测试。当它们在控制器中时,一切都会顺利进行。我将它们移出控制器,并添加了一个异步,以确保我们等待。否则,我将调用的中的函数。现在,一旦我使用async/await,控制器中的函数就会认为没有用户,因为它没有等待。 有几个关于异步等待的SO问题,但我没有找到一个解决我的问题。我确实验证了返回了我的用户,并添加了控制台日志来显示路径。 节点猫鼬异步等待似

  • 任务或任务 我们也可以定义自己的可实现对象。对象应具有以下资格。 < li >它有一个GetAwaiter()方法(实例方法或扩展方法); < li >其GetAwaiter()方法返回一个Awaiter。在下列情况下,对象是一个标识符: < ul > < li >它实现INotifyCompletion或ICriticalNotifyCompletion接口; < li >它有一个IsCompl

  • 我通读了Dart/flatter中的Async/Await/then,试图理解为什么aysnc函数中的Await不会等到完成后再继续。在我的UI中,有一个按钮调用一个异步方法来返回一个位置,该位置总是返回null,并且不等待函数完成。 该函数将调用推送到一个新的UI页面,该页面选择一个位置,并应返回一个结果。如何使该函数等待结果?我不是在使用异步吗?

  • 我需要修改一个现有的程序,它包含以下代码: 但这在我看来非常奇怪,首先是在select中使用和。根据斯蒂芬·克利里的回答,我应该能够放弃这些。 然后第二个,它选择结果。这是不是意味着任务根本不是异步的,而是同步执行的(这么多的努力是徒劳无功的),或者任务是异步执行的,当它完成后,查询的其余部分将被执行? 我是否应该按照Stephen Cleary的另一个答案,像下面这样编写上述代码: 而且像这样完