如何在 nodejs/knexjs 中停止异步数据库调用
How to stop asynchronous database calls in nodejs/knexjs
我想说的是,上周我一直被这个问题困扰。
我正在尝试将锻炼添加到我的数据库中,并且我从前端收到了 3 件事:作为字符串的锻炼名称,一个名为 exercises
的数组,其中包含该锻炼中每个锻炼的对象。最后,一个名为 sets
的数组是一个二维数组,每个数组包含每个集合的对象
const exercises = [
{name: ''}
]
const sets = [
[
{
reps: '',
kg: ''
}
]
]
我正在使用 knex,我想将这些数据插入到我的数据库中。这是我的代码:
app.post('/newworkout', (req, res) => {
const {workoutName, exercises, sets} = req.body;
const loggedSets = [];
let haveRoutinesFinished = false;
let haveExercisesFinished = false;
PushRoutinesToDB = () => {
db('routines')
.returning('id')
.insert({
userid: user.id,
name: workoutName
})
.then(routineID => {
workoutInfo.routineID = routineID[0];
haveRoutinesFinished = true;
console.log('1')
return db('loggedroutines')
.insert({
userid: user.id,
routineid: workoutInfo.routineID,
routinedate: new Date()
})
})
}
PushExercisesToDB = () => {
exercises.map(exercise => {
console.log('2')
db('exercises')
.insert({
userid: user.id,
routineid: workoutInfo.routineID,
name: exercise.name
})
.returning('id')
.then(exerciseID => {
console.log('exercise id', exerciseID)
exerciseIDArray.push(exerciseID[0])
console.log("exerciseIDArray", exerciseIDArray)
haveExercisesFinished = true;
return db('loggedexercises')
.insert({
userid: user.id,
routineid: workoutInfo.routineID,
exerciseid: exerciseID[0]
})
})
})
}
PushSetsToDB = () => {
sets.map((setsArray, i) => {
setsArray.map(set => {
loggedSets.push({
userid: user.id,
routineid: workoutInfo.routineID,
exerciseid: exerciseIDArray[i],
reps: set.reps,
kg: set.kg
})
})
})
console.log(loggedSets)
db('loggedsets').insert(loggedSets)
}
PushRoutinesToDB()
console.log(haveRoutinesFinished)
if (haveRoutinesFinished === true) {
PushExercisesToDB()
}
if (haveExercisesFinished === true) {
PushSetsToDB()
}
})
代码本身可以工作,但是由于第一个数据库调用是异步的,所以第二个不工作,它依赖于第一个。我尝试使用回调来解决这个问题,但这只会导致我的代码无法 运行。有什么想法吗?
由于您的函数是 Asynchronous
即使第一个函数尚未完成,线程也会继续。
使用async/await
一定能解决你的问题。
注意评论以查看更改
app.post('/newworkout', async (req, res) => { //asynchronous Function
const {workoutName, exercises, sets} = req.body;
const loggedSets = [];
let haveRoutinesFinished = false;
let haveExercisesFinished = false;
PushRoutinesToDB = async () => { //asynchronous Function
db('routines')
.returning('id')
.insert({
userid: user.id,
name: workoutName
})
.then(routineID => {
workoutInfo.routineID = routineID[0];
haveRoutinesFinished = true;
console.log('1')
return db('loggedroutines')
.insert({
userid: user.id,
routineid: workoutInfo.routineID,
routinedate: new Date()
})
})
}
PushExercisesToDB = async () => { //asynchronous Function
exercises.map(exercise => {
console.log('2')
db('exercises')
.insert({
userid: user.id,
routineid: workoutInfo.routineID,
name: exercise.name
})
.returning('id')
.then(exerciseID => {
console.log('exercise id', exerciseID)
exerciseIDArray.push(exerciseID[0])
console.log("exerciseIDArray", exerciseIDArray)
haveExercisesFinished = true;
return db('loggedexercises')
.insert({
userid: user.id,
routineid: workoutInfo.routineID,
exerciseid: exerciseID[0]
})
})
})
}
PushSetsToDB = async () => { //asynchronous Function
sets.map((setsArray, i) => {
setsArray.map(set => {
loggedSets.push({
userid: user.id,
routineid: workoutInfo.routineID,
exerciseid: exerciseIDArray[i],
reps: set.reps,
kg: set.kg
})
})
})
console.log(loggedSets)
db('loggedsets').insert(loggedSets)
}
// Now your all functions are asynchronous You can call them in series with 'await'
await PushRoutinesToDB()
await PushExercisesToDB()
await PushSetsToDB()
})
我想说的是,上周我一直被这个问题困扰。
我正在尝试将锻炼添加到我的数据库中,并且我从前端收到了 3 件事:作为字符串的锻炼名称,一个名为 exercises
的数组,其中包含该锻炼中每个锻炼的对象。最后,一个名为 sets
的数组是一个二维数组,每个数组包含每个集合的对象
const exercises = [
{name: ''}
]
const sets = [
[
{
reps: '',
kg: ''
}
]
]
我正在使用 knex,我想将这些数据插入到我的数据库中。这是我的代码:
app.post('/newworkout', (req, res) => {
const {workoutName, exercises, sets} = req.body;
const loggedSets = [];
let haveRoutinesFinished = false;
let haveExercisesFinished = false;
PushRoutinesToDB = () => {
db('routines')
.returning('id')
.insert({
userid: user.id,
name: workoutName
})
.then(routineID => {
workoutInfo.routineID = routineID[0];
haveRoutinesFinished = true;
console.log('1')
return db('loggedroutines')
.insert({
userid: user.id,
routineid: workoutInfo.routineID,
routinedate: new Date()
})
})
}
PushExercisesToDB = () => {
exercises.map(exercise => {
console.log('2')
db('exercises')
.insert({
userid: user.id,
routineid: workoutInfo.routineID,
name: exercise.name
})
.returning('id')
.then(exerciseID => {
console.log('exercise id', exerciseID)
exerciseIDArray.push(exerciseID[0])
console.log("exerciseIDArray", exerciseIDArray)
haveExercisesFinished = true;
return db('loggedexercises')
.insert({
userid: user.id,
routineid: workoutInfo.routineID,
exerciseid: exerciseID[0]
})
})
})
}
PushSetsToDB = () => {
sets.map((setsArray, i) => {
setsArray.map(set => {
loggedSets.push({
userid: user.id,
routineid: workoutInfo.routineID,
exerciseid: exerciseIDArray[i],
reps: set.reps,
kg: set.kg
})
})
})
console.log(loggedSets)
db('loggedsets').insert(loggedSets)
}
PushRoutinesToDB()
console.log(haveRoutinesFinished)
if (haveRoutinesFinished === true) {
PushExercisesToDB()
}
if (haveExercisesFinished === true) {
PushSetsToDB()
}
})
代码本身可以工作,但是由于第一个数据库调用是异步的,所以第二个不工作,它依赖于第一个。我尝试使用回调来解决这个问题,但这只会导致我的代码无法 运行。有什么想法吗?
由于您的函数是 Asynchronous
即使第一个函数尚未完成,线程也会继续。
使用async/await
一定能解决你的问题。
注意评论以查看更改
app.post('/newworkout', async (req, res) => { //asynchronous Function
const {workoutName, exercises, sets} = req.body;
const loggedSets = [];
let haveRoutinesFinished = false;
let haveExercisesFinished = false;
PushRoutinesToDB = async () => { //asynchronous Function
db('routines')
.returning('id')
.insert({
userid: user.id,
name: workoutName
})
.then(routineID => {
workoutInfo.routineID = routineID[0];
haveRoutinesFinished = true;
console.log('1')
return db('loggedroutines')
.insert({
userid: user.id,
routineid: workoutInfo.routineID,
routinedate: new Date()
})
})
}
PushExercisesToDB = async () => { //asynchronous Function
exercises.map(exercise => {
console.log('2')
db('exercises')
.insert({
userid: user.id,
routineid: workoutInfo.routineID,
name: exercise.name
})
.returning('id')
.then(exerciseID => {
console.log('exercise id', exerciseID)
exerciseIDArray.push(exerciseID[0])
console.log("exerciseIDArray", exerciseIDArray)
haveExercisesFinished = true;
return db('loggedexercises')
.insert({
userid: user.id,
routineid: workoutInfo.routineID,
exerciseid: exerciseID[0]
})
})
})
}
PushSetsToDB = async () => { //asynchronous Function
sets.map((setsArray, i) => {
setsArray.map(set => {
loggedSets.push({
userid: user.id,
routineid: workoutInfo.routineID,
exerciseid: exerciseIDArray[i],
reps: set.reps,
kg: set.kg
})
})
})
console.log(loggedSets)
db('loggedsets').insert(loggedSets)
}
// Now your all functions are asynchronous You can call them in series with 'await'
await PushRoutinesToDB()
await PushExercisesToDB()
await PushSetsToDB()
})