获取卡车位置后,我正在为卡车制作类似Uber的应用程序,我必须找到负载已过帐的匹配卡车。但是我陷入了回调地狱。能否请您提及同时有效地完成工作和提高性能的最佳方法。我正在express.js中创建后端,并使用了Mysql和MongoDB这两个数据库。任何帮助都非常有用。
const express = require('express');
const bodyParser = require('body-parser');
const mysql = require('mysql');
const request = require('request');
const bcrypt = require('bcrypt');
const cors = require('cors');
const moment = require('moment');
const mongoose = require('mongoose');
mongoose.connect("mongodb://localhost/Location");
const mongoConn = mongoose.connection;
mongoConn.on('connected',function () {
console.log("mongo connected");
});
mongoConn.on('disconnected',function () {
console.log("mongo disconnected");
});
mongoConn.on('error', console.error.bind(console, 'connection error:'));
mongoConn.once('open', function() {
console.log("mongo connection opened");
});
const LocationSchema = mongoose.Schema({
truck_id:Number,
user_id:Number,
longitude:Number,
latitude:Number,
created_at:Number,
status:Number
});
const Location = mongoose.model('Location',LocationSchema);
const app = express();
app.listen(3002 ,()=> {
console.log('server is listening at port 3002');
});
app.use(cors());
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
next();
});
app.use( bodyParser.json() ); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
const db = mysql.createConnection({
host : '127.0.0.1',
user : 'root',
password : '',
database : 'truck'
});
db.connect(function(err) {
if (err) {
console.error('error connecting: ' + err.stack);
return;
}
console.log('connected as id ' + db.threadId);
});
app.get('/view-trucks',verifyUser,(req,res)=>{
let truck_ids = [];
let truck_locations;
let load_id = req.query.id;
let sql = 'SELECT * FROM tr_post_load WHERE id = '+ db.escape(load_id);
db.query(sql,function (error, results, fields) {
if(error){console.log('error is '+error);res.status(200).send({status:'error'});throw error;}
if(results.length > 0){
let load_from_lat = results[0].from_lat;
let load_from_long = results[0].from_long;
let load_to_lat = results[0].to_lat;
let load_to_long = results[0].to_long;
let find_Trucks_sql = 'SELECT * FROM tr_truck WHERE user_id != '+results[0].user_id+' AND truck_capacity_id = ? AND body_type_id = ? AND truck_length_id = ?';
db.query(find_Trucks_sql,[results[0].truck_capacity_id,results[0].body_type_id,results[0].truck_length_id],function (error, results, fields) {
if (error) {console.log('error is ' + error);res.status(200).send({status: 'error'});throw error;}
if(results.length > 0) {
for (let a = 0; a <= results.length; a++) {
if(typeof results[a] === 'object'){
truck_ids.push(results[a].id);
}
}
console.log("truck ids are "+truck_ids);
if(truck_ids.length > 0){
// fetch location from mongodb
let locationQuery = Location.find({truck_id:{$in:truck_ids},status:1}).lean();
locationQuery.exec(function (err,locations) {
if (err){console.log("mongo error is "+err);res.status(200).send({status: 'error'});}
truck_locations = locations;
if(truck_locations.length > 0) {
console.log("truck length ay 847 is " + truck_locations.length);
for (let i = 0; i <= truck_locations.length; i++) {
if (typeof truck_locations[i] === "object") {
console.log("my truck value at line 849 is " + truck_locations[i]);
let diff = findTimeDiff(truck_locations[i].created_at);
console.log("time difference is " + diff);
if (diff) {
if (truck_locations[i].latitude !== null && truck_locations[i].longitude !== null) {
let dist = distance(load_from_lat, load_from_long, truck_locations[i].latitude, truck_locations[i].longitude);
if (dist !== null) {
console.log("if dist truck id is " + truck_locations[i].truck_id);
let truck_routes_sql = "SELECT * FROM tr_route WHERE truck_id = " + db.escape(truck_locations[i].truck_id);
db.query(truck_routes_sql, function (err, truck_routes, fields) {
if (err) {console.log("error while fetching truck routes is " + err);throw err;}
console.log("truck routed are " + JSON.stringify(truck_routes));
console.log("my truck value at line 868 is " + truck_locations[i]);
if (truck_routes.length > 0) {
for (let j = 0; j <= truck_routes.length; j++) {
console.log("current trucks route is " + JSON.stringify(truck_routes[j]));
if (typeof truck_routes[j] === "object" && truck_routes[j].from_lat !== null && truck_routes[j].from_long !== null) {
let route_distance_from = distance(load_to_lat, load_to_long, truck_routes[j].from_lat, truck_routes[j].from_long);
let route_ditance_to = distance(load_to_lat, load_to_long, truck_routes[j].to_lat, truck_routes[j].to_long);
if (route_distance_from !== null || route_ditance_to !== null) {
console.log("i am in truck route distance at line 869 and truck is " + JSON.stringify(truck_locations[i]));
let find_truck_sql = "SELECT * FROM tr_truck WHERE id = " + db.escape(truck_routes[j].truck_id);
db.query(find_truck_sql, function (error, truck, fields) {
if (err) {
console.log("error while fetching truck routes is " + err);
throw err;
}
// console.log("truck on line 874 is "+JSON.stringify(truck[0])+"and truck length is "+truck.length);
if (truck.length > 0 && typeof truck[0] !== "undefined") {
console.log("final truck found on line 884 is " + JSON.stringify(truck[0]));
console.log("885 mytruck at position "+i+" is "+JSON.stringify(truck_locations[i]));
truck_locations[i].truck = truck[0];
console.log("after adding object and truck is " + JSON.stringify(truck_locations));
}
});
} else {
// mytrucks.splice(i,1);
}
}
}
} else {
// truck_locations.splice(i, 1);
console.log("i is " + i + " no routes found and my_trucks are now " + JSON.stringify(truck_locations));
}
});
} else {
// mytrucks.splice(i,1);
}
}
} else {
// mytrucks.splice(i,1);
}
}
}
}
res.status(200).send(truck_locations);
//end of location
});
}else{
res.status(200).send("no truck found");
}
}else{
res.status(200).send("no truck found");
}
});
}else{
res.status(200).send({status:'notExist'});
}
});
});
function distance(lat1, lon1, lat2, lon2) {
let p = 0.017453292519943295; // Math.PI / 180
let c = Math.cos;
let a = 0.5 - c((lat2 - lat1) * p)/2 +
c(lat1 * p) * c(lat2 * p) *
(1 - c((lon2 - lon1) * p))/2;
return 12742 * Math.asin(Math.sqrt(a)); // 2 * R; R = 6371 km
}
function findTimeDiff(truck_created_at) {
let truck_time = truck_created_at;
truck_time = moment(truck_time);
let nowTime = moment().utcOffset("+05:30").toDate().getTime();
nowTime = moment(nowTime);
return nowTime.diff(truck_time, "minutes");
}
答案 0 :(得分:1)
以@dvsoukup的评论为基础,您应该首先通读this article about JavaScript promises。引入了承诺,以缓解此回调地狱,并且做得很棒。
然后,如果您使用的是Nodejs 8或更高版本,则应调查async/await。在查看异步/等待之前,请确保对Promises没问题,因为它在后台使用了Promise。您可以跳过此步骤,直接进入异步/等待状态,但最终您会发现自己回到了我的想象中。
这两种方法都应该停止回调地狱,并使代码更具可读性。
答案 1 :(得分:0)
有一个软件包promise-mysql
,其中已将Bluebird promise包装在mysql
软件包中。
这将允许您使用相同的mysql函数,但是可以使用返回的promise(以及最终的async / await)来代替回调函数,就像这样。
async handleRequest(req, res, next) {
try {
const loadQuery = `SELECT * FROM tr_post_load WHERE id = ${db.escape(load_id)}`;
const loads = await db.query(sqlQuery);
if (loads.length === 0) {
throw new Error('Load not found');
}
const load = loads[0];
const load_from_lat = load.from_lat;
const load_from_long = load.from_long;
const load_to_lat = load.to_lat;
const load_to_long = load.to_long;
const truckQuery = `SELECT * FROM tr_truck WHERE user_id != ${load.user_id} AND truck_capacity_id = ? AND body_type_id = ? AND truck_length_id = ?`;
const trucks = await db.query(
truckQuery,
[ load.truck_capacity_id, load.body_type_id, load.truck_length_id ]
);
if(trucks.length > 0) {
for (let a = 0; a <= trucks.length; a++) {
if(typeof trucks[a] === 'object') {
truck_ids.push(trucks[a].id);
}
}
...
// more code and queries to follow
...
} catch (error) {
console.log('error is '+error);
res.status(200).send({status:'error'});
throw error;
}
}