2015-01-24 3 views
2

Я работаю над Express. При запуске он подключается к серверу Redis и к серверу PostgreSQL. Я хотел бы подождать, пока оба соединения не удастся, прежде чем запускать экспресс-сервер. Теперь, если бы я ожидал только одного обратного вызова, я мог бы инициировать сервер Express в этом обратном вызове. Но как лучше всего это делать, ожидая более чем одной асинхронной операции? Я новичок в этом. Есть ли хороший идиоматический образец для такого рода вещей? Может быть, группировать обещания вместе или ...?Подождите несколько соединений db перед запуском экспресс-сервера?

+0

Я не знаю о сервере Redis, но новое соединение с PostgreSQL занимает менее 100 мс, едва ли можно отложить начало приложения Express. Кроме того, приложение будет получать доступ к серверу асинхронно, так что эта логика избыточна. Взгляните на [pg-prom] (https://github.com/vitaly-t/pg-promise), он хорошо справляется с асинхронным доступом к Postgres. –

+0

В моем случае сервер PostgreSQL и серверы Redis выполнялись на компьютерах в другом месте в Интернете, чем на экспресс-сервере, поэтому соединения иногда занимали чуть больше 100 мс. Даже если все они были на одном сервере, я думаю, я все равно буду беспокоиться о доступе к БД (например, в стартовом коде Express), который еще не был официально подключен. –

ответ

3

Обещания - это то, что вы хотите.

Вы можете использовать .all() на множестве обещаний дождаться их завершения. Вы не упомянули, какую библиотеку Promise вы используете, но это довольно универсально. вот документация Bluebird: https://github.com/petkaantonov/bluebird/blob/master/API.md#all---promise

+0

Спасибо! Я новичок в плане обещаний и не использовал конкретную реализацию (пока), но у меня была догадка, что обещания могут помочь. Не знал о Bluebird. Поэтому я полагаю, что в моем случае будет массив из двух обещаний: один для соединения redis и один для соединения postgres. И Bluebird имеет функцию promisifyAll, которая выглядит полезной. –

+0

@BobbyCircle Да, это правильно. Все библиотеки обещаний имеют какую-то «все» функцию, благодаря которой вы можете сделать одно обещание из множества обещаний. – Brad

0

Обещания, вероятно, являются идиоматическим способом решения этой проблемы. Вам придется «обещать» свои функции, которые возвращают обратные вызовы, чтобы превратить их в то, что возвращает и разрешает обещания, но тогда Promise.all() будет работать нормально. Я лично использую Bluebird для разработки nodejs и регулярно обещаю существующие функции или целые модули, которые используют асинхронные обратные вызовы.


Если вы не иначе, используя библиотеку, которая может promisify без обещанных функций, то вы можете просто использовать счетчик, чтобы отслеживать, когда все ваши обратные вызовы выполняются. Это «старомодный» способ делать что-то, но работает отлично. Такая операция работает следующим образом:

function setup(fn) { 
    // initialize counter to number of async operations 
    var counter = 3; 
    function checkDone() { 
     --counter; 
     if (counter <= 0) { 
      fn(); 
     } 
    } 

    firstAsyncFunction(...., checkDone); 
    secondAsyncFunction(...., checkDone); 
    thirdAsyncFunction(...., checkDone); 

} 

setup(function() { 
    // this will get called when all the initial async operations are done 
}); 
+0

Большое спасибо. Функции «promisify» выглядят действительно полезными здесь. –

Смежные вопросы