node.js:从函数返回未按预期运行

gea*_*ead 17 javascript mongodb node.js

我是javascript/node.js的新手,我遇到以下代码的问题.这是API调用的处理程序.第二代码片断就像是第一次,但有一个额外的数据库查询Merchant.findOne(...),及其所用'newTransaction.save()函数嵌套更深一层.

两个代码段都正确返回'output'变量值.但是,第二个代码段还没有正确地将"newTransaction"保存到Mongo数据库.

我敢肯定,这个问题有多么/时从newTransaction.save(函数(ERR,交易){..}但我返回的代码似乎无法得到它理顺做.

我一直在寻找整个互联网试图理解和解决这个问题,但没有成功.任何帮助表示赞赏......

这是更老,更简单的代码,按预期工作:

 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));
            }
        });
    }
Run Code Online (Sandbox Code Playgroud)

这是不将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));
            }
        });
    }
Run Code Online (Sandbox Code Playgroud)

Joh*_*Siu 2

我对你的 2 版本进行了比较:

在此输入图像描述

检查1

票证报价

  • 两个版本的回调是相同的
  • processorlocalCurrency是不同的

    1. 传入exchangeRate回调是否正确?

检查2

新交易.保存

  • newTransaction和 .save 的回调设置相同

    1. 检查(console.log())设置中使用的值new Transaction({...})
    2. 检查transaction回调收到的对象
    3. 检查/调试Transaction.save()的代码。

我认为问题不在于您发布的代码。两个版本都return reply(output);在 newTransaction.save 的回调中到达。问题很可能出在 Transaction 类或 Transaction.save() 逻辑内部。

我能想到的一种情况是交易失败时:

  1. 交易对象可用(即使交易失败)
  2. 事务类/Transaction.save() 不会写入数据库,因为事务失败
  3. Transaction.save() 将transaction对象传递给回调,但不设置err,即使应该这样做。