提问人:Vibi 提问时间:5/24/2023 更新时间:5/24/2023 访问量:16
异步代码在 Node 和 Express Server 中无序运行
Asynchronous code running out of order with Node and Express Server
问:
我是全栈开发的新手,并且有一个简单的 Express 服务器,它从 HTML 表单中获取输入,然后使用 mysql npm 包查询 mysql 服务器。然后,来自 mysql 服务器的数据被重新格式化为我发送到客户端的对象,以使用 chart.js 制作图表和表格。当我调用函数来查询 mysql 并创建对象时,会出现问题,代码运行无序,并且在我使用 .render 发送对象时对象最终为空白。
索引.js服务器代码:
const express = require('express')
const app = express()
const path = require('path')
var mysql = require('mysql');
const charts = require('chart.js')
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: false }));
app.set('view engine', 'ejs')
app.set('views', path.join(__dirname, '/views'))
app.use(express.static(path.join(__dirname,'public')))
app.get('/chart', (req,res) => {
res.render('charttest.ejs')
})
var allData = {}
var tableArr = new Array(0)
async function getTable(tablename,checkedtimes){ //This is the function that connects to mysql
var mysql = require('mysql'); //and creates the objects
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '####',
database: '###'
});
connection.connect();
const dataList = new Array(checkedtimes.length)
var count = 0;
let allTimes =""
for(i = 0; i < checkedtimes.length; i++){
allTimes += `\`${checkedtimes[i]}\`,`
}
allTimes = allTimes.substring(0,allTimes.length -1)
connection.query(`SELECT Date,${allTimes} FROM ${tablename}` ,function (error, results, fields) {
if (error) throw error;
let dataTimes = new Array(0)
for(let i = 0; i < results.length; i++){
dataTimes.push(results[i].Date)
}
let sets = new Array(0)
for(let i = 0; i < checkedtimes.length; i++){
let tableData = {}
let obj = {}
let dataProfit = new Array(0)
for(let j = 0; j < results.length; j++){
dataProfit.push(results[j][checkedtimes[i]])
}
obj.data = dataProfit
sets.push(obj)
tableData.Time = checkedtimes[i]
tableData.profit = dataProfit.reduce((a,b)=>a+b)
tableArr.push(tableData)
}
allData.datasets = sets
allData.labels = dataTimes
console.log("get table:",allData)
console.log("gettable:",tableArr)
//allData and tableArr are the final objects to be sent to client side
})
}
app.post('/chart', (req,res) => {
let prem = req.body.prem;
let maxloss = req.body.loss
const checkedtimes = req.body.times
async function asyncTable(tablename,checkedtimes) {
await getTable(tablename,checkedtimes)
console.log("INSIDE asyncTable")
console.log("async table:" ,tableArr)
console.log("async table:",allData)
//Sending the objects to a HTML file where the chart and table are displayed
res.render('linechart.ejs',{allData:allData,tableArr: tableArr})
}
switch(prem) { //only including one case here just to show the problem
case '0.75'://
if(maxloss === "1x"){
asyncTable("finalprem75loss1x",checkedtimes)
}
break;
}
app.listen(3000, () => {
console.log("LISTENING ON PORT 3000")
})
当我运行这段代码时,当我到达 .render 命令时,这两个对象是空白的。我在代码的不同区域包含了console.logs,以显示对象的值,以尝试理解正在发生的事情,它给了我这个输出:
LISTENING ON PORT 3000
[
'09:45:00',
'10:30:00',
'11:30:00',
'12:30:00',
'13:00:00',
'14:00:00'
]
INSIDE asyncTable
async table: []
async table: {}
get table: {
datasets: [
{ data: [Array] },
{ data: [Array] },
{ data: [Array] },
{ data: [Array] },
{ data: [Array] },
{ data: [Array] }
],
labels: [
//A bunch of data
]
}
gettable: [
{ Time: '09:45:00', profit: 148.0900000000002 },
{ Time: '10:30:00', profit: 118.05999999999985 },
{ Time: '11:30:00', profit: 82.70999999999984 },
{ Time: '12:30:00', profit: 171.4700000000004 },
{ Time: '13:00:00', profit: 187.71999999999966 },
{ Time: '14:00:00', profit: 161.81999999999996 }
]
这与我的预期完全不符。它首先运行 getTable 函数中的 console.log(checkedtimes),但随后会立即跳到在 asyncTable 函数中运行 console.log,然后再次切换回 getTable 函数。我是异步编程的新手,所以我不确定我是否正确使用异步,但我的目的是让 getTable 函数(这需要一段时间才能运行,所以我假设这就是扰乱执行顺序的原因)在运行 asyncTable 中的下一行并将对象发送到客户端之前先完全运行。
我遇到的另一个问题是,由于执行顺序被搞砸了,我猜 .render 发生在 getTable 完成之前,因此发送到客户端的对象只是空白对象。这显示在 console.logs 中,其中 asyncTable 函数中的对象被打印为空白,即使它们应该在调用 getTable 函数之后出现。如果您需要更多信息或需要我的ejs文件,我也可以提供它们。
答: 暂无答案
评论
await
connection.query()