Node.js: Возврат из функции, не действующей как ожидалось
Я очень новичок в javascript/ node.js, и у меня возникают проблемы со следующим кодом. Это обработчик API для вызова. Второй сегмент кода похож на 1-й, за исключением того, что есть дополнительный поиск в базе данных Merchant.findOne(...), и поэтому функция newTransaction.save() вложен на один уровень глубже.
Оба сегмента кода правильно возвращают значение "output". Однако второй сегмент кода НЕ также правильно сохраняет "newTransaction" в базе данных Mongo.
Я уверен, что проблема связана с тем, как/когда код возвращается из newTransaction.save(функция (err, transaction) {..}, но я не могу понять, что она исправлена.
Я смотрел по всему Интернету, пытаясь понять и исправить это, без успеха. Любая помощь приветствуется...
Вот более старый, более простой код, который работает как ожидалось:
handler : function(request, reply) {
var output = {
"success": true,
"operations": [],
"epoch": Date.now()
};
Terminal.findById(request.payload.deviceNumber, function (err, terminal) {
if (err) {
return reply(Boom.internal('Error looking up terminal.', err));
}
if (terminal) {
ticket.quote("bitstamp", "USD", 1, function (err, exchangeRate) {
if (err) {
console.error(err);
return reply(Boom.internal('Error obtaining ticket quote.', err));
}
var newTransaction = new Transaction({
terminal: request.payload.deviceNumber,
merchant: terminal.merchant,
ccExchangeRate: exchangeRate.buy,
fiatAmtDue: request.payload.transactionValue,
ccAmtDue: ccAmtDueTruncated
});
newTransaction.save(function (err, transaction){
if (err) {
return reply(Boom.internal('Error creating new transaction.', err));
}
output.operations.push(
{
"control": "KeyPairGenControl",
"rand": cc.pseudoRandomBytes(32).toString('hex'),
"follow": {
"url": "/pos/v1/AddressAndEncKey",
"post": {
"transactionId": transaction.transactionId
}
}
}
);
return reply(output);
});
});
} else {
return reply(Boom.internal('Error looking up terminal.', err));
}
});
}
Вот новый код, который НЕ сохраняет данные newTransaction в Mongo DB.
handler : function(request, reply) {
var output = {
"success": true,
"operations": [],
"epoch": Date.now()
};
Terminal.findById(request.payload.deviceNumber, function (err, terminal) {
if (err) {
return reply(Boom.internal('Error looking up terminal.', err));
}
if (terminal) {
Merchant.findOne({merchantId: terminal.merchant}, function(err, merchant) {
if (err) {
console.log('Cannot find merchant');
return reply(output);
}
var processor = merchant.backendPaymentProcessor.name;
var localCurrency = merchant.localFiatCurrency;
//###################
ticket.quote(processor, localCurrency, 1, function (err, exchangeRate) {
if (err) {
console.error(err);
return reply(Boom.internal('Error obtaining ticket quote.', err));
}
var newTransaction = new Transaction({
terminal: request.payload.deviceNumber,
merchant: terminal.merchant,
ccExchangeRate: exchangeRate.buy,
fiatAmtDue: request.payload.transactionValue,
ccAmtDue: ccAmtDueTruncated
});
newTransaction.save(function (err, transaction){
if (err) {
return reply(Boom.internal('Error creating new transaction.', err));
}
output.operations.push(
{
"control": "KeyPairGenControl",
"rand": cc.pseudoRandomBytes(32).toString('hex'),
"follow": {
"url": "/pos/v1/AddressAndEncKey",
"post": {
"transactionId": transaction.transactionId
}
}
}
);
return reply(output);
});
//return reply(output);
});
//###################
});
} else {
return reply(Boom.internal('Error looking up terminal.', err));
}
});
}
Ответы
Ответ 1
Я сделал разницу в вашей 2 версии:
![введите описание изображения здесь]()
Проверить 1
ticket.quote
Проверить 2
newTransaction.save
Я не думаю, что проблема связана с кодом, который вы опубликовали. Обе версии достигли return reply(output);
внутри newTransaction.save обратного вызова. Очень вероятно, что проблема заключается в классе Transaction или Transaction.save().
Один сценарий, о котором я могу думать, - это когда транзакция завершилась неудачно:
- Объект транзакции доступен (даже для неудавшейся транзакции)
- Класс транзакции /Transaction.save() не записывается в db, поскольку транзакция завершилась неудачно
- Transaction.save() передает
transaction
объект для обратного вызова, но НЕ устанавливает err
, даже если это необходимо.
Ответ 2
Mongoose, имеющий функцию для указания имени коллекции в рамках схемы или в качестве третьего аргумента при объявлении модели. В противном случае он будет использовать множественную версию, указанную именем, которое вы сопоставляете с моделью.
Официальный документ Mongoose, имеющий следующий оператор:
Mongoose по умолчанию создает имя коллекции, передавая имя модели методу utils.toCollectionName. Этот метод плюрализует имя. Установите этот параметр, если вам нужно другое имя для вашей коллекции.
схема отображенные:
new Schema({ <key>: <value>},
{ collection : '<collection name>' }); // collection name
модель отображенные:
mongoose.model('<Model name>',
new Schema({ <key>: <value>}),
'<collection name>'); // collection name
Вы также можете найти то же самое здесь