首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >node.js:从函数返回未按预期执行

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

Stack Overflow用户
提问于 2016-08-16 21:16:26
回答 2查看 314关注 0票数 17

我是javascript/node.js的新手,在使用下面的代码时遇到了问题。这是API调用的处理程序。第二个代码段和第一个代码段一样,除了有一个额外的数据库查找Merchant.findOne(...),因此'newTransaction.save()‘函数嵌套得更深一层。

两个代码段都正确地返回了'output‘变量值。但是,第二个代码段也不能正确地将'newTransaction‘保存到Mongo数据库。

我很确定这个问题与代码从newTransaction.save(function (err,transaction){..}返回的方式/时间有关,但我似乎无法解决这个问题。

我已经在互联网上到处寻找,试图理解和解决这个问题,但没有成功。任何帮助我们都很感激。

以下是较旧的、更简单的代码,它们可以按预期工作:

代码语言:javascript
复制
 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中的新代码。

代码语言:javascript
复制
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));
            }
        });
    }
EN

回答 2

Stack Overflow用户

发布于 2016-08-19 06:10:22

我对你的第二个版本做了一个比较:

检查1

ticket.quote

两个不同的version

  • processor,的
  • 回调是不同的

代码语言:javascript
复制
1. Is `exchangeRate` pass into callback correct?

检查2

newTransaction.save

.save的

  • newTransaction和callback是设置相同的

代码语言:javascript
复制
1. Check(console.log()) the values used in setting up `new Transaction({...})`
2. Check `transaction` object received by callback
3. Check/debug the code of Transaction.save().

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

我能想到的一种情况是,当事务失败时:

因为transaction failed

  • Transaction.save()将transaction对象传递给回调,而不是设置err,所以类事务对象可用(即使是失败的transaction)

  • Transaction类/ Transaction.save()也不会写入db )。
票数 2
EN

Stack Overflow用户

发布于 2016-08-24 18:48:14

Mongoose具有在模式下指定集合名称的功能,或者在声明模型时作为第三个参数。否则,它将使用映射到模型的名称所给出的复数形式。

Mongoose官方文档,声明如下:

默认情况下,Mongoose通过将模型名称传递给utils.toCollectionName方法来生成集合名称。此方法将名称复数。如果需要为集合指定不同的名称,请设置此选项。

schema-mapped:

代码语言:javascript
复制
new Schema({ <key>: <value>}, 
       { collection : '<collection name>' });   // collection name

模型映射:

代码语言:javascript
复制
mongoose.model('<Model name>', 
           new Schema({ <key>: <value>}), 
           '<collection name>');     // collection name

You may also find same here

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38976033

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档