使用Q.all()时出现瓶颈问题

时间:2019-04-17 03:04:26

标签: node.js es6-promise q

我是NodeJS和Promise的新手,并使用Q Promise库。我正面临一种情况,我需要解析承诺数组,然后使用结果。我已经使用Q.all([arrayOfPromise])来解决所有承诺。在这里,每个承诺都在执行数据库操作,因此活动数据库连接的数量越过连接池的大小,并且会出错。

我已经阅读了Q库文档-https://github.com/kriskowal/q 但是找不到任何解决方案。

np.random.seed(1997)

df = pd.DataFrame(np.random.randn(10, 4))
first_stats = scipy.stats.linregress(df.index,df[0])
second_stats = scipy.stats.linregress(df.index,df[1])

有人可以建议采用更好的方法吗?预先感谢。

2 个答案:

答案 0 :(得分:1)

Q只是一个实用程序,不明白为什么他们会处理数据库特定的问题。

您可以做的一件事是设计一些类似于队列的机制来控制允许的并发数据库操作的总大小。按顺序输入文字,控制arrayOfPromise的大小。

我不知道您的问题的性质,但是为什么不通过一个批处理查询而不是许多getById来获取数据?

答案 1 :(得分:0)

根据其他用户的建议,对您的问题的更好解决方案是使用WHERE id IN ( .. )类型的查询。

您遇到的问题是操作并发。 N个操作正在并行执行,这引起了问题。在最坏的情况下,它们甚至可能导致意外崩溃或NodeJS进程的资源使用增加。

Q或本机Promise没有控制执行并发的方法。如果绝对必须使用Promise.all,我建议使用Bluebird.mapLink)。

const process = () => {
    const arrayOfIds = [id1, id2, id3, id4 .... idn] 

    return Bluebird.map(arrayOfIds, 
        (id) => getById(id),
        { concurrency: 5 } // Default +Inifinity
    )
      .then(resultArray => {
        // utilization of result array
      })
}

当然,您必须确保getById返回的诺言与Bluebird兼容(不确定Q诺言,但原生Promise是)