Node.js 在执行异步函数之前呈现的Express JS页面

Node.js 在执行异步函数之前呈现的Express JS页面,node.js,asynchronous,express,routing,Node.js,Asynchronous,Express,Routing,我对express.js路由有问题。我想在用户打开/restaurant/map时获取所有餐厅。问题是函数gm.geocode是异步的,所以在执行该函数之前呈现页面。当页面/餐厅/地图加载时,如何在正确的时间获取可变地图数据?正确的方法是什么 var express = require('express'); var router = express.Router(); var gm = require('googlemaps'); var fs=require('fs'); var stati

我对express.js路由有问题。我想在用户打开/restaurant/map时获取所有餐厅。问题是函数gm.geocode是异步的,所以在执行该函数之前呈现页面。当页面/餐厅/地图加载时,如何在正确的时间获取可变地图数据?正确的方法是什么

var express = require('express');
var router = express.Router();
var gm = require('googlemaps');
var fs=require('fs');
var staticDB=require('./staticDB.js');
var mapsData=[];


/* GET home page. */
router.get('/', function (req, res, next) {
//not important
});

router.get('/map/', function (req, res, next) {
    var counter=0;
    console.log('Request URL:', req.originalUrl);
    for (i = 0; i < staticDB.addresses.addresses.length; i++) {
        gm.geocode(staticDB.addresses.addresses[i].street + ", " + staticDB.addresses.addresses[i].city, function (err, data){
            mapsData.push({
                "name": staticDB.restaurants.restaurants[counter].name,
                "location": data.results[0].geometry.location
            });
            counter++;
        }, false);
    }
    res.render('map', {
        title: 'title',
        restaurants: mapsData
    });
});

module.exports = router;
var express=require('express');
var router=express.router();
var gm=需要(“谷歌地图”);
var fs=需要('fs');
var staticDB=require('./staticDB.js');
var mapsData=[];
/*获取主页*/
router.get('/',函数(req,res,next){
//不重要
});
get('/map/',函数(req,res,next){
var计数器=0;
log('Request URL:',req.originalUrl);
对于(i=0;i
切勿使用常规
for
循环来处理异步流。有一些模块可以为您处理这些场景,例如,甚至是承诺。在您的情况下,您的代码应该如下所示,使用(我没有测试它):


它很管用,谢谢!在express.js中是否有其他一些好的实践来处理这些异步调用(在本例中是google maps api)?那么,
async
模块是一个非常好的替代方案。但您也可以使用
承诺
。只要在npm.org上搜索承诺,你就会看到很多使用这种方法的模块。只是别忘了把答案标为已接受。
router.get('/map/', function (req, res, next) {
  var counter=0;
  console.log('Request URL:', req.originalUrl);
  async.each(staticDB.addresses.addresses, function (address, cb) {
    gm.geocode(address.street + ", " + address.city, function (err, data){
        mapsData.push({
            "name": staticDB.restaurants.restaurants[counter].name,
            "location": data.results[0].geometry.location
        });
        counter++;
        cb();
    }, false);
  }, function (err) {
    if (err) {
      return res.render('error', { error: err });
    }
    res.render('map', {
      title: 'title',
      restaurants: mapsData
    });
  });
});