在执行异步函数之前呈现的 Express JS 页面
Express JS page rendered before async function was executed
我的 express.js 路由有问题。我想在用户打开 /restaurant/map 时获取所有餐厅。问题是函数 gm.geocode 是异步的,因此在执行该函数之前呈现页面。我如何在正确的时间获得变量 mapsData,所以当页面 /restaurant/map 加载时?这样做的正确方法是什么?
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;
切勿使用常规 for
循环来处理异步流。有些模块可以为您处理这些场景,例如 async
, or even promises. In your case, your code should look like this, using async.each
(我没有测试):
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
});
});
});
我的 express.js 路由有问题。我想在用户打开 /restaurant/map 时获取所有餐厅。问题是函数 gm.geocode 是异步的,因此在执行该函数之前呈现页面。我如何在正确的时间获得变量 mapsData,所以当页面 /restaurant/map 加载时?这样做的正确方法是什么?
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;
切勿使用常规 for
循环来处理异步流。有些模块可以为您处理这些场景,例如 async
, or even promises. In your case, your code should look like this, using async.each
(我没有测试):
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
});
});
});