Expressjs无法顺序执行,并且函数返回不起作用

时间:2018-10-08 18:18:20

标签: node.js express mongoose

我是node / express js的新手,正在尝试执行以下命令。该控件在函数调用“ var nextVersion = getNextContractVersion(cid)”之后执行这些行,甚至在该函数返回响应之前也是如此。结果,newVersion的值未更新为Contract对象。此外,与更新的nextVersion不同,函数getNextContractVersion(cid)返回未定义。

如何解决此问题,请提出建议。还有,调用功能的正确方法是吗?

// Package imports
const express = require('express');
var router = express.Router();
const mongoose = require('mongoose');

//Local imports
var { Customer } = require('../models/customer');
var { Contract } = require('../models/contract');

router.put('/:cid/contracts', (req, res) => {

    var cid = req.params.cid;

    var nextVersion =getNextContractVersion(cid);


    var contract;
    if (validateCustomerId(cid)) {
        req.body.contract.forEach((item) => {
            contract = new Contract({
                customerID: cid,
                startDate: item.startDate,
                endDate: item.endDate,
                conditions: item.conditions,
                price: item.price,
                author: item.author,
                version: nextVersion
            });

        });

        contract.save((err, docs) => {

            if (!err) {
                Customer.findOneAndUpdate({ customerID: cid }, { $push: { contract: contract } },
                    { safe: true, upsert: true, new: true }).populate({ path: 'contract' }).exec((err1, docs1) => {

                        if (!err1) {
                            res.send(docs1).status(200);
                        } else {
                            console.log('Error is adding a new contract:' + JSON.stringify(err1, undefined, 2));
                        }
                    });
            } else {
                console.log('Error is updating a new customer:' + JSON.stringify(err, undefined, 2));
            }

        });
    } else {
        res.status(400).send('Bad Request - Invalid input!')
    }

});



function getNextContractVersion(cid) {

    var nextVersion=1;


    Contract.findOne({ customerID: cid }).sort({version: 'descending'}).exec((err, doc) => {

        if (!err && doc != null) {

            var currentVersion = parseInt(doc.version);

            nextVersion = currentVersion + 1;

        } 

    });

    return nextVersion;
}

1 个答案:

答案 0 :(得分:1)

您正在混合同步和异步代码。

Contract.findOne({ customerID: cid }).sort({version: 'descending'}).exec((err, doc) => {
        if (!err && doc != null) {
            var currentVersion = parseInt(doc.version);
            nextVersion = currentVersion + 1;
        } 
    });

上面的代码有效地说:“转到数据库,找到这些对象之一,然后在将来完成的任何时候,运行exec块中的代码。”

promises的思维方式中推理异步代码的方法之一。

这是一个半伪实现:

router.put('/:cid/contracts', (req, res) => {

    var cid = req.params.cid;

    return getTheMostRecentContract(cid)
    .then(function(oldContract){
        var nextVersion = oldContract.version +1;

        if(!validateCustomerId(cid)){
            return res.status(400).send('Bad Request - Invalid input!');
        }

        var contract;
        var savePromises = [];
        req.body.contract.forEach((item) => {
            contract = new Contract({
                customerID: cid,
                startDate: item.startDate,
                endDate: item.endDate,
                conditions: item.conditions,
                price: item.price,
                author: item.author,
                version: nextVersion
            });

            savePromises.push(contract.save());
        });

        return Promise.all(savePromises);
    })
    .then(function(resultOfAllSavePromises){
        //rest of code here              
    }).catch(function(error){
        console.log('Error is updating a new customer:' + JSON.stringify(err, undefined, 2));
        return res.status(400);
    })

});


function getTheMostRecentContract(cid) {
    return Contract.findOne({ customerID: cid }).sort({version: 'descending'});
}

不过,作为实践,请让数据库控制您的自动增量值。该代码在交通繁忙的环境中不起作用。