2015-06-21 2 views
2

Я в экспресс-маршрутизаторе, рендеринг с Jade и вытаскивание данных из MongoDB для подготовки к этому. Есть ли лучший способ собрать все необходимые данные по сравнению со следующей конструкцией? Обратите внимание, что нет никакой зависимости между ресторанами столов, клиентами и драйверами, требующими первого возврата - мне просто нужно, чтобы все три выполнялись перед рендерингом страницы.Есть ли лучший метод вызовов функций зависимостей против их укладки?

Некоторые из этих каскадных вызовов в некоторых случаях становятся довольно глубокими. Должна быть лучшая конструкция, не так ли?

router.get('/iframe_map/:restaurantid/:customerid', function(req, res, next) { 
    Restaurant.findOne({'_id': req.params.restaurantid}, '-_id address name phone status lat lng LatLng marker', function(restaurantErr, restaurantDoc) { 
    Customer.findOne({'_id': req.params.customerid}, '-_id address name phone status lat lng LatLng marker', function(customerErr, customerDoc) { 
     Driver.find({}, '-_id letterOrdinal address firstName lastName phone status lat lng LatLng marker', {sort: {letterOrdinal: 1}}, function(driverErr, driverDocs) { 
     res.render('iframe_map', { 
      title:    "Google Map", 
      defaultZoomLevel: 12, 
      defaultCityState: ", San Diego, CA", 
      oRestaurant:  restaurantDoc, 
      oCustomer:   customerDoc, 
      oDrivers:   driverDocs 
     }); // End of res.render() 
     }); // End of Driver.find() 
    });  // End of Customer.find() 
    });  // End of Restaurant.find() 
});   // End of router.get() 
+0

вы можете использовать Асинхронный Водопад https://github.com/caolan/async#waterfall –

+0

@Michelem Хм ... * IF * мои функции БД имели зависимости между собой, тогда я бы согласился. (Неплохая попытка.) Поскольку мои функции БД не имеют зависимостей между собой, я думаю, что async.parallel может быть более уместным здесь. https://github.com/caolan/async#paralleltasks-callback (спасибо.) –

+0

Да, конечно, Водопад - это всего лишь пример, модуль Async - это то, что вы должны попробовать (и если для вас это лучше использовать, то используйте его) –

ответ

2

Вот ваш код переписан с асинхронным Waterfall:

router.get('/iframe_map/:restaurantid/:customerid', function(req, res, next) { 
    var obj = {}; 
    async.waterfall([ 
     function(done) { 
      Restaurant.findOne({'_id': req.params.restaurantid}, '-_id address name phone status lat lng LatLng marker', function(err, items) { 
       if (err) done(err); 
       obj.restaurant = items; 
       done(null, obj); 
      }); 
     }, 
     function(obj, done) { 
      Customer.findOne({'_id': req.params.customerid}, '-_id address name phone status lat lng LatLng marker', function(err, items) { 
       if (err) done(err); 
       obj.customer = items; 
       done(null, obj); 
      }); 
     }, 
     function(obj, done) { 
      Driver.find({}, '-_id letterOrdinal address firstName lastName phone status lat lng LatLng marker', {sort: {letterOrdinal: 1}}, function(err, items) { 
       if (err) done(err); 
       obj.driver = items; 
       done(null, obj); 
      }); 
     } 
    ], function (err, result) { 
     res.render('iframe_map', { 
      title:    "Google Map", 
      defaultZoomLevel: 12, 
      defaultCityState: ", San Diego, CA", 
      oRestaurant:  result.restaurant, 
      oCustomer:   result.customer, 
      oDrivers:   result.driver 
     }); 
    }); 
}); 
+0

Спасибо за быстрый ответ. Я удивлен, что вы смогли собрать его так быстро. Как я уже упоминал выше, нет взаимозависимостей между БД, поэтому цепочка вызовов кажется немного ненужной, особенно учитывая путаницу параметров, которую это вводит. Здесь мы имеем несколько переменных «obj», каждый из которых представляет различные типы объектов. Аналогично, у нас есть несколько ссылок на функцию «обратный вызов». Исходный код был длиннее 16 строк, и теперь он в два раза превышает длину в 33 строках кода. (Конечно, исходный код был расширен.) Я собираюсь изучить async.parallel, хотя. Опять же, спасибо. –

+0

О, я думаю, что всегда лучше иметь код, который легко читать (от вас, но также и в основном от других), чем иметь его «короткий», поэтому я считаю, что это хороший подход, вместо того, чтобы использовать «обратный ад», когда вам нужно сделайте что-нибудь подобное. Тем не менее, как вы сказали, я написал это очень быстро, вы можете его усовершенствовать, например, вы можете передать все аргументы, которые хотите выполнить обратный вызов, вместо того, чтобы помещать все в один объект. Добро пожаловать. –