我正在用事务编写mysql查询,但是它不等待完成,甚至在函数执行之前就返回结果。
有人可以帮助我知道如何使函数等待响应吗?
调用函数是这样的:
deductUserPoint = await helper.deductUserPoint2(data)
console.log('===============================================')
console.log(deductUserPoint)
if (deductUserPoint.isError === true) {
let error = {}
error.isError = true
error.message = 'Unable to deduct amount'
error.error = deductUserPoint.error
res.status(200).json(error)
} else {
res.status(200).json({ 'isError': false, 'message': 'success' })
}
我总是以deductUserPoint
的身份获得undefined
,因为它不等待deductUserPoint2
到return response
deductUserPoint2
如下:
async deductUserPoint2(params) {
try {
this.db.connection.getConnection(function(err, conn) {
console.log('1111111111')
conn.beginTransaction(function(err) {
if (err) {
throw err
}
console.log(params)
console.log('2222222222')
conn.query('SELECT id, `expert_id`, user_id, status FROM `call` WHERE `id` = ?', [params.callId], function (error, callInfo, fields) {
if (error) {
return conn.rollback(function() {
throw error
})
}
console.log('33333333')
let callLength = null
if (params.callMinute === 'entire_day') {
callLength = 'entire_day'
} else {
const callMinutes = Math.round(params.callMinute)
if (callMinutes <= 30) {
callLength = '30_min'
} else if (callMinutes >= 31 && callMinutes <= 60) {
callLength = '60_min'
} else if (callMinutes >= 61 && callMinutes <= 90) {
callLength = '90_min'
} else if (callMinutes >= 91) {
callLength = '120_min'
}
}
console.log('4444444444')
conn.query('SELECT `amount` FROM `expert_charges` WHERE `status` = "active" AND `call_length` = ? AND `expert_id` = ?', [callLength, callInfo[0].expert_id], function (error, points, fields) {
if (error) {
return conn.rollback(function() {
throw error
})
}
console.log('555555555555')
let data = {
fromUserId: callInfo[0].user_id,
fromUserType: 'user',
to_user_id: 0,
to_user_type: null,
category: 'call',
type: 'debited',
callId: params.callId,
amount: points[0].amount,
note: params.note,
point: points[0].amount,
current_balance_point: 0
}
let input = Object.values(data)
conn.query('INSERT INTO wallet (`from_user_id`, `from_user_type`, `to_user_id`, `to_user_type`, `category`, `type`, `call_id`, `amount`, `note`, `point`, `current_balance_point`) VALUES ?', [[input]], function (error, wallet, fields) {
if (error) {
return conn.rollback(function() {
throw error
})
}
console.log('666666666666')
conn.query('UPDATE user SET total_points = total_points - ? WHERE id = ?', [points[0].amount, callInfo[0].user_id], function (error, updateUserPoint, fields) {
if (error) {
return conn.rollback(function() {
throw error
})
}
console.log('7777777777')
conn.commit(function(err) {
if (err) {
return conn.rollback(function() {
throw err
})
}
console.log('888888888')
return {
"isError": false,
"status": "success"
}
})
})
})
})
})
})
})
} catch (error) {
console.log(error)
return {
"isError": true,
"error": error.toString()
}
}
它显示的错误是:
undefined
(node:4197) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'isError' of undefined
at router.post (/Users/msmexmac/node/msmex-backend/msmex-api/api/wallet.js:120:23)
at process._tickCallback (internal/process/next_tick.js:68:7)
(node:4197) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:4197) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
1111111111
{ callId: 5, note: 'Deduction for call', callMinute: 25 }
2222222222
33333333
4444444444
555555555555
666666666666
7777777777
888888888
答案 0 :(得分:0)
您不能使用这样的异步函数,必须返回一个Promise才能等待回调。您的函数将必须像这样结束:
function deductUserPoint2(params) {
return new Promise(function (resolve, reject) {
try {
this.db.connection.getConnection(function (err, conn) {
console.log('1111111111')
conn.beginTransaction(function (err) {
if (err) {
return reject(err)
}
console.log(params)
console.log('2222222222')
conn.query('SELECT id, `expert_id`, user_id, status FROM `call` WHERE `id` = ?', [params.callId], function (error, callInfo, fields) {
if (error) {
return conn.rollback(function () {
return reject(error)
})
}
console.log('33333333')
let callLength = null
if (params.callMinute === 'entire_day') {
callLength = 'entire_day'
} else {
const callMinutes = Math.round(params.callMinute)
if (callMinutes <= 30) {
callLength = '30_min'
} else if (callMinutes >= 31 && callMinutes <= 60) {
callLength = '60_min'
} else if (callMinutes >= 61 && callMinutes <= 90) {
callLength = '90_min'
} else if (callMinutes >= 91) {
callLength = '120_min'
}
}
console.log('4444444444')
conn.query('SELECT `amount` FROM `expert_charges` WHERE `status` = "active" AND `call_length` = ? AND `expert_id` = ?', [callLength, callInfo[0].expert_id], function (error, points, fields) {
if (error) {
return conn.rollback(function () {
return reject(error)
})
}
console.log('555555555555')
let data = {
fromUserId: callInfo[0].user_id,
fromUserType: 'user',
to_user_id: 0,
to_user_type: null,
category: 'call',
type: 'debited',
callId: params.callId,
amount: points[0].amount,
note: params.note,
point: points[0].amount,
current_balance_point: 0
}
let input = Object.values(data)
conn.query('INSERT INTO wallet (`from_user_id`, `from_user_type`, `to_user_id`, `to_user_type`, `category`, `type`, `call_id`, `amount`, `note`, `point`, `current_balance_point`) VALUES ?', [[input]], function (error, wallet, fields) {
if (error) {
return conn.rollback(function () {
return reject(error)
})
}
console.log('666666666666')
conn.query('UPDATE user SET total_points = total_points - ? WHERE id = ?', [points[0].amount, callInfo[0].user_id], function (error, updateUserPoint, fields) {
if (error) {
return conn.rollback(function () {
return reject(error)
})
}
console.log('7777777777')
conn.commit(function (err) {
if (err) {
return conn.rollback(function () {
return reject(err)
})
}
console.log('888888888')
return resolve({
"isError": false,
"status": "success"
})
})
})
})
})
})
})
})
} catch (error) {
console.log(error)
return resolve({
"isError": true,
"error": error.toString()
})
}
})
}
然后,您使用reject(err)
代替throw err
,用resolve(value)
代替return value
。
另一种方法是按照建议的https://jsfiddle.net/richardmarais/Lwpygd17/1/使用utils.promisify
。