Проблема с горлышком бутылки при использовании Q.all () - PullRequest
0 голосов
/ 17 апреля 2019

Я новичок в nodeJS и обещаниях и использую библиотеку Q обещаний.Я сталкиваюсь с ситуацией, когда мне нужно разрешить массив обещаний, а затем использовать результат.Я использовал Q.all ([arrayOfPromise]) для разрешения всех обещаний.Здесь каждое обещание выполняет операцию с БД, поэтому число активных соединений с БД пересекает размер пула соединений и получает ошибку.

Я просмотрел документацию библиотеки Q - https://github.com/kriskowal/q Но не смог найти никакого решения.

const process = () => {
    const arrayOfIds = [id1, id2, id3, id4 .... idn] 
        // getById is fetching data from DB asynchronously 
    const arrayOfPromises = arrayOfIds.map(id => getById(id))

    return Q.all([arrayOfPromises])
      .then(resultArray => {
        // utilization of result array
      })
}

Кто-нибудь может предложить лучший подход, чтобы сделать то же самое?Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 17 апреля 2019

Q - это просто утилита, не понимаю, почему они решат проблему, связанную с БД.

Одна вещь, которую вы можете сделать, - это разработать механизм, подобный очереди, чтобы контролировать общий размер разрешенных одновременных операций с БД. В слове заказа, управляйте размером вашего arrayOfPromise.

Я не знаю природу вашей проблемы, но почему бы вам не получить данные в одном пакетном запросе вместо множества getById?

0 голосов
/ 21 апреля 2019

Как предлагают другие пользователи, лучшим решением вашей проблемы будет использование типа запроса WHERE id IN ( .. ).

Проблема в вашем случае - параллелизм операций. N операций выполняются параллельно, что является причиной проблемы. В худшем случае они могут даже вызвать неожиданные сбои или увеличение использования ресурсов для вашего процесса NodeJS.

Q или собственный Promise не имеет метода для контроля параллелизма выполнения. Если вам абсолютно необходимо использовать Promise.all, я бы предложил использовать Bluebird.map ( Link ).

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 обещания, но собственное обещание есть)

...