node.js:从函数返回不按预期方式
我对javascript / node.js很陌生,而且遇到下面的代码有问题。 这是API调用的处理程序。 第二个代码段就像第一个代码段一样,除了有一个额外的数据库查找Merchant.findOne(…),因此'newTransaction.save()'函数嵌套更深一层。
两个代码段都正确地返回“输出”variables值。 但是,第二个代码段不能正确地将“newTransaction”保存到Mongo数据库中。
我很确定这个问题与如何/从newTransaction.save(function(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数据保存到MongoDB中的新代码。
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)); } }); }
我做了你的2版本的差异:
检查1
ticket.quote
- 这两个版本的callback是相同的
-
processor
,localCurrency
是不同的-
exchangeRate
传入callback是否正确?
-
检查2
newTransaction.save
-
newTransaction
和.save的callback设置完全相同- 检查(console.log())用于设置
new Transaction({...})
- 检查callback接收的
transaction
对象 - 检查/debuggingTransaction.save()的代码。
- 检查(console.log())用于设置
我不认为这个问题是你发布的代码。 两个版本都达到了return reply(output);
在newTransaction.save的callback里面。 非常可能的问题是在Transaction类或Transaction.save()逻辑内。
我能想到的一种情况是交易失败:
- 交易对象是可用的(即使对于失败的交易)
- 事务类/ Transaction.save()不会写入数据库,因为事务失败
- Transaction.save()将
transaction
对象传递给callback,但不设置err
,即使它应该。
Mongoose具有在模式下指定集合名称的function,或者在声明模型时作为第三个参数。 否则,它将使用您映射到模型的名称给出的复数forms。
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
你也可以在这里find