Javascript竞争条件多个承诺连接字符串

Posted

技术标签:

【中文标题】Javascript竞争条件多个承诺连接字符串【英文标题】:Javascript race condition multiple promises concat string 【发布时间】:2021-04-22 01:59:49 【问题描述】:

我有一个接收用户名数组的函数。对于每一个,我需要获取连接 ID 并连接到另一个数组中。但我认为我确实遇到了一些竞争条件问题,这些问题可能会发生冲突并连接更少的结果......

const getConnections = async function (usernames) 

    let connections = [];

    await Promise.all(usernames.map(async (username) => 

        try 

            let connsFound = await dynamo.getConnectionsByUsername(username);

            if (connsFound && connsFound.length > 0)
                connections = connections.concat(connsFound);

         catch (error) 
            console.error('ERROR GET CONNECTIONS', error)
        

    ));

    return connections;

;

连接的结果是一个数组,所以我想将结果合并到 var 连接...但是 .concat 不合并,它会创建一个新数组,所以我需要做一个 'var = var .concat(newArray)'

我担心这不安全,并且在某些操作中它会碰撞并覆盖某些结果...

有没有更好的方法?

干杯

【问题讨论】:

return connsFound; 代替,并使用let connections = await Promise.all(... (Promise.all 将解析为 Promise 结果的数组,以相同的顺序,这正是您首先想要的,没有需要在这里连接任何东西) 【参考方案1】:

javascript 是单线程的,所以总是最多有一个函数可以运行和访问connections。你应该没有任何问题。

但是,没有理由这样做。由于您已经在使用async/await,因此您只需创建一个数组数组和flatten:

const getConnections = async function (usernames) 
    const connections = await Promise.all(usernames.map(async (username) => 

        try 
            return await dynamo.getConnectionsByUsername(username);
         catch (error) 
            console.error('ERROR GET CONNECTIONS', error);
            return [];
        

    ));
    return connections.flat();
;

.flat 相对较新,但应该很容易编写自定义帮助函数来实现相同的功能。

【讨论】:

在 try/catch 中不需要 return await -- 只需 return 直接承诺 @Joe 那你就没法处理拒绝了。 你可以做return dynamo.getConnectionsByUsername(username).catch((e) => ... ) @Joe 实际上,那个 try-catch 块没用,但这是 OP 的方法。 @Joe 我知道,但这与您最初的建议不同。

以上是关于Javascript竞争条件多个承诺连接字符串的主要内容,如果未能解决你的问题,请参考以下文章

访问在QThread内部由Pynput侦听器调用的线程中访问的SQLite3数据库连接时关注竞争条件

使用拆分“读取”和“写入”数据库连接时 Laravel 中的竞争条件

避免 redis 竞争条件

在 psycopg2 中为连接的所有查询设置架构:设置 search_path 时获取竞争条件

将 INDEX/MATCH 与多个条件和多个匹配项连接起来

关注在 QThread 内由 Pynput 侦听器调用的线程中访问的 SQLite3 数据库连接时的竞争条件