我正在API中为订单数据实体构建模型类。目前,该实体有2个端点,一个端点用于检索摘要数据/orders/{id}/summary
,另一个端点用于支付数据/orders/{id}/payment
。摘要有效100%,付款端点获取所有数据,除非存在辅助数据库查询。
我的order.js模型中的代码:
'use strict';
/* Include MySQL connection */
var dbConnection = require(appDir + process.env.PATH_LIB + 'database');
/* Include PaymentMethod model */
var PaymentMethod = require('./paymentmethod');
class Order {
constructor (data, requestTemplate) {
this.data = data;
switch (requestTemplate) {
case 'summary':
this.data.platform = _getPlatform(data.TakeALot);
this.data.source = _getSource(data.idKalahariOrder,data.idAffiliate,data.TakeALot);
this.data.reference = _getExternalReference(data.idKalahariOrder,data.AffiliateReference);
break;
case 'payment':
this.data.health = _getHealth(data.Auth);
this.data.timeline = _getTimeline(data.Auth);
break;
};
}
getPayments () {
var paymentList = [];
var paymentMethods = [];
if (this.data.PaymentMethod) {
paymentList.push(this.data.PaymentMethod);
};
if (this.data.PaymentMethods) {
this.data.PaymentMethods.split(',').forEach(function(e){
if (paymentList.indexOf(e) == -1) {
paymentList.push(e);
}
})
};
for (var i = 0; i < paymentList.length; i++) {
console.log(paymentList[i]);
paymentMethods.push(new PaymentMethod(this.data.idOrder,paymentList[i]));
};
console.log(paymentMethods);
this.data.payments = paymentMethods;
}
}
/* Find a single ORDER SUMMARY data */
Order.findSummaryById = function (id, callback) {
dbConnection(function(err, conn){
conn.query('SELECT <<query text removed>> WHERE o.idOrder = ?', [id], function(err, rows) {
if (err) return callback(err);
callback(null, new Order(rows[0], 'summary'));
});
conn.release();
})
};
/* Find a single ORDER PAYMENT data */
Order.findPaymentById = function (id, callback) {
dbConnection(function(err, conn){
conn.query('SELECT <<query text removed>> WHERE o.idOrder = ?', [id], function(err, rows) {
if (err) return callback(err);
let order = new Order(rows[0], 'payment');
order.getPayments();
callback(null, order);
});
conn.release();
})
};
/* Build order timeline */
function _getTimeline(status) {
<<business logic removed>>
return orderTimeline;
}
/* Determine order health */
function _getHealth(status) {
<<business logic removed>>
return health;
}
/* Determine order source */
function _getSource(idKalahariOrder, idAffiliate, TakeALot) {
<<business logic removed>>
return source;
}
/* Determine client platform */
function _getPlatform(clientId) {
<<business logic removed>>
return platform;
}
/* Determine external reference */
function _getExternalReference(idKalahariOrder, AffiliateReference) {
<<business logic removed>>
return reference;
}
module.exports = Order;
我的paymentmethod.js模型中的代码:
'use strict';
/* Include MySQL connection */
var dbConnection = require(appDir + process.env.PATH_LIB + 'database');
class PaymentMethod {
constructor(idOrder, paymentType) {
var SQL = '';
switch (paymentType) {
case 'Credit Card':
SQL = 'SELECT <<query text removed>> WHERE idOrder = ?';
break;
default:
SQL = 'SELECT <<query text removed>> WHERE idOrder = ?';
};
dbConnection(function(err, conn){
conn.query(SQL, [idOrder], function (err, data) {
if (err) return callback(err);
if (data) {
this.paymentType = paymentType;
this.paymentAmount = data.paymentAmount;
this.paymentReference = data.paymentReference;
this.paymentState = data.paymentState;
}
});
conn.release();
});
}
}
module.exports = PaymentMethod;
问题似乎出在
getPayments
类的Order
方法中。当执行push paymentMethods.push(new PaymentMethod(this.data.idOrder,paymentList[i]));
时,似乎由于异步,在PaymentMethod
的新类实例被推入数组之前,将执行以下代码行。我什至尝试先将新的类实例分配给一个变量,然后再推送它,但是它具有相同的影响。有任何想法吗?编辑:
我将PaymentMethod类更改为:
class PaymentMethod {
constructor(idOrder, paymentType) {
var SQL = '';
switch (paymentType) {
case 'Credit Card':
SQL = 'SELECT <<SQL text>> WHERE idOrder = ?';
break;
default:
SQL = 'SELECT <<SQL text>> WHERE idOrder = ?';
};
return new Promise(function (resolve) {
this.loadData(SQL, idOrder).then(function (data) {
console.log(data);
this.paymentType = paymentType;
this.paymentAmount = data.paymentAmount;
this.paymentReference = data.paymentReference;
this.paymentState = data.paymentState;
resolve (this);
});
});
};
loadData (SQL, idOrder) {
console.log('fetching data ...');
return new Promise (function (resolve) {
dbConnection(function(err, conn){
conn.query(SQL, [idOrder], function (err, data) {
if (err) return callback(err);
if (data) {
resolve (data);
}
});
conn.release();
});
})
};
}
并且,在这里调用它:
getPayments () {
var paymentList = [];
var paymentMethods = [];
if (this.data.PaymentMethod) {
paymentList.push(this.data.PaymentMethod);
};
if (this.data.PaymentMethods) {
this.data.PaymentMethods.split(',').forEach(function(e){
if (paymentList.indexOf(e) == -1) {
paymentList.push(e);
}
})
};
for (var i = 0; i < paymentList.length; i++) {
console.log(paymentList[i]);
//var paymentDet = new PaymentMethod(this.data.idOrder,paymentList[i]);
new PaymentMethod(this.data.idOrder,paymentList[i]).then(function(data) {
console.log('detail:',data);
paymentMethods.push(data);
});
};
console.log(paymentMethods);
this.data.payments = paymentMethods;
}
但是,仍然没有运气....
最终解决方案
订单类别:
class Order {
constructor (data, requestTemplate) {
this.data = data;
switch (requestTemplate) {
case 'summary':
this.data.platform = _getPlatform(data.TakeALot);
this.data.source = _getSource(data.idKalahariOrder,data.idAffiliate,data.TakeALot);
this.data.reference = _getExternalReference(data.idKalahariOrder,data.AffiliateReference);
break;
case 'payment':
this.data.health = _getHealth(data.Auth);
this.data.timeline = _getTimeline(data.Auth);
break;
};
}
getPayments () {
var self = this;
return new Promise(function (resolve) {
var paymentList = [];
var paymentMethods = [];
if (self.data.PaymentMethod) {
paymentList.push(self.data.PaymentMethod);
};
if (self.data.PaymentMethods) {
self.data.PaymentMethods.split(',').forEach(function(e){
if (paymentList.indexOf(e) == -1) {
paymentList.push(e);
}
})
};
for (var i = 0; i < paymentList.length; i++) {
new PaymentMethod(self.data.idOrder,paymentList[i]).then(function(data) {
paymentMethods.push(data);
if (paymentMethods.length == paymentList.length) {
self.data.payments = paymentMethods;
resolve(self);
}
})
};
})
}
}
PaymentMethod类:
class PaymentMethod {
constructor(idOrder, paymentType) {
var SQL = '';
switch (paymentType) {
case 'Credit Card':
SQL = 'SELECT <<query text>> WHERE idOrder = ?';
break;
default:
SQL = 'SELECT <<query text>> WHERE idOrder = ?';
};
var self = this;
return new Promise(function (resolve) {
self.loadData(SQL, idOrder).then(function (data) {
self.paymentType = paymentType;
self.paymentAmount = data.paymentAmount;
self.paymentReference = data.paymentReference;
self.paymentState = data.paymentState;
resolve (self);
}).catch(function(error) {
console.log('Error occurred!', error);
});
}).catch(function(error) {
console.log('Error occurred!', error);
});
}
loadData (SQL, idOrder) {
return new Promise (function (resolve) {
dbConnection(function(err, conn){
conn.query(SQL, [idOrder], function (err, data) {
if (err) return callback(err);
if (data) {
resolve (data[0]);
}
});
conn.release();
});
}).catch(function(error) {
console.log('Error occurred!', error);
});
};
}
实例化一个新的Order实例的代码:
Order.findPaymentById = function (id, callback) {
dbConnection(function(err, conn){
conn.query('SELECT <<query text>> WHERE o.idOrder = ?', [id], function(err, rows) {
if (err) return callback(err);
let order = new Order(rows[0], 'payment');
order.getPayments().then(function(){
callback(null, order);
});
});
conn.release();
})
};
最佳答案
为了打印结果并返回正确的数据,我建议在getPayments函数中返回一个promise-这样,被调用者函数将可以访问.then闭包内的所有付款方式。
例如:
被调用者功能:
getPayments().then(function(paymethods) {
//use paymethods array here for something
console.log(paymethods);
});
getPayments函数:
function getPayments () {
var paymentList = [];
var paymentMethods = [];
if (this.data.PaymentMethod) {
paymentList.push(this.data.PaymentMethod);
};
if (this.data.PaymentMethods) {
this.data.PaymentMethods.split(',').forEach(function(e){
if (paymentList.indexOf(e) == -1) {
paymentList.push(e);
}
})
};
return new Promise(function(resolve) {
var last = false;
for (var i = 0; i < paymentList.length; i++) {
if (i === paymentList.length-1) { last=true }
console.log(paymentList[i]);
new PaymentMethod(this.data.idOrder,paymentList[i]).then( function(data) {
console.log('detail:',data);
paymentMethods.push(data);
if (last) {
resolve(paymentMethods);
}
});
};
});
}