只有在 nodejs 路由器上完成所有事务后,才返回 ajax 调用



我正在尝试对节点页面进行ajax调用,该节点页面根据ajax调用中传递的参数对数据库执行一些操作。我面临的问题是控件被传递回 html 页面(我正在使用警报来测试请求完成(,该页面甚至在 nodejs 端完成所有数据库事务之前就启动了 ajax 调用。为了更好地理解,我添加了较小版本的代码。

Origin: HTML page
<div id="paramList">
    <form action='import/other' method='POST' style='display:none;' id="h_form">
    <label><input type="checkbox" value="opt1" />Option 1</label>
    <label><input type="checkbox" value="opt2" />Option 2</label>
    <label><input type="checkbox" value="opt3" />Option 3</label>
    <label><input type="checkbox" value="opt4" />Option 4</label>
    <label><input type="checkbox" value="opt5" />Option 5</label>
    </form>
</div>
<button onclick="startValidation()">Submit</button>
Handler: JS
function startValidation() {
    var paramlist = '';
    $("#paramList input[type='checkbox']").each(function() {
        if ($(this).is(":checked")) {
            paramlist += "'" + $(this).val() + "',";
        }
    });
    paramlist = paramlist.substr(0, paramlist.length - 1);
    var req = $.ajax({
        url: '/import/validate',
        type: 'POST',
        data: { paramList: paramlist, fileName: finalName }
    })
    req.done(function(data, status) {
        alert('Data validated successfully. Select Ok to go to validate sheet: ' + status);
        var form = $("#h_form");
        form.submit();
        //redirect to the other page and load data from the latest insert
    });
    req.fail(function(xOptions, textStatus) {
        alert('Error occured!: ' + textStatus);
    });
}

服务器端脚本

NodeJS: Router
router.post('/validate',function(req,res){
    var paramlist = req.body.paramList;
    var fileName = req.body.fileName;
    var cli = modImport.parseFile(fileName,paramlist);
    res.send(cli);
});
//Import module: modImport.js
module.exports.executeQuery = function(strSQL, operationType, tableName, cb, param) {
    logger.log('debug','running query: '+strSQL);
    var request = new sql.Request(connection);
    request.query(strSQL,function(err, recordset) {
        if(err){
            logger.error('ERROR in '+operationType+' ON '+tableName+': '+err);
        }
        logger.info(operationType+' ON '+tableName+' successful!');
        if(cb){
            cb(param);
        }
    });
},
module.exports.parseFile: function(filePath, validateParam){
    sql.connect(config).then(function() {
        var arr = [];
        arr.push(data);arr.push(validateParam);
        arr.push(tName);
        var delQ = "DELETE FROM [Tbl_TempData]";
        util.executeQuery(delQ,'DELETION','[Tbl_TempData]', module.exports.bulkImportIntoTempData, arr);
        console.log("deletion completed");
    }).catch(function(err) {
        logger.error('other error: '+err); 
    });
},
module.exports.bulkImportIntoTempData: function(arr){
    var data = arr[0];
    var validateParam = arr[1];
    var tName = arr[2];
    var bInQ = "INSERT INTO [Tbl_TempData] (field1,field2,field3) VALUES ";
    data.forEach(function(rec, index){
        var keys = Object.keys(rec);
        var kLen = keys.length - 1;
        keys.forEach(function(datum,cursor){                
            bInQ += "('" + datum + "','" + rec[datum] + "','" + tName + ")";
            if(cursor < kLen){
                bInQ += ",";
            }
        });
    });
    module.exports.executeQuery(bInQ,'BULK INSERTION','[Omni_TempSurveyData]',module.exports.processForTempCalc,validateParam);
},
module.exports.processForTempCalc: function(validateParam){
    var strSQL = "DELETE FROM [Tbl_TempCalc]";
    util.executeQuery(strSQL,'DELETION','[Tbl_TempCalc]',module.exports.insertIntoTempCalc,validateParam);
},
module.exports.insertIntoTempCalc: function(validateParam){
    var strSQL = "INSERT INTO .....";
    //some transformations here from other tables
    util.executeQuery(strSQL,'INSERTION','[Tbl_TempCalcData]');

},
module.exports.insertIntoBlankCalc: function(validateParam){
    var strSQL = "INSERT INTO .....";
    util.executeQuery(strSQL,'INSERTION','[Tbl_BlankCalcData]');
    //TODO: return the ajax call
}

ajax 完成后,用户将被重定向到从上次插入的表中加载数据的页面。但由于警报是在最终插入之前弹出的,因此重定向的页面对用户显示为空白。请建议如何克服这种情况。

如果其他函数工作正常,这将解决问题:

NodeJS: Router
    router.post('/validate',function(req,res){
        var paramlist = req.body.paramList;
        var fileName = req.body.fileName;
        var cli = modImport.parseFile(fileName,paramlist,function(){  
          res.send(cli);
        });
    });
    //Import module: modImport.js
    module.exports.executeQuery = function(strSQL, operationType, tableName, cb, param) {
        logger.log('debug','running query: '+strSQL);
        var request = new sql.Request(connection);
        request.query(strSQL,function(err, recordset) {
            if(err){
                logger.error('ERROR in '+operationType+' ON '+tableName+': '+err);
            }
            logger.info(operationType+' ON '+tableName+' successful!');
            if(cb){
                cb(param);
            }
        });
    },
    module.exports.parseFile: function(filePath, validateParam,callback){
        sql.connect(config).then(function() {
            var arr = [];
            arr.push(data);arr.push(validateParam);
            arr.push(tName);
            var delQ = "DELETE FROM [Tbl_TempData]";
            util.executeQuery(delQ,'DELETION','[Tbl_TempData]', module.exports.bulkImportIntoTempData, arr);
            console.log("deletion completed");
            callback()
        }).catch(function(err) {
            logger.error('other error: '+err); 
            callback()
        });
    },
    module.exports.bulkImportIntoTempData: function(arr){
        var data = arr[0];
        var validateParam = arr[1];
        var tName = arr[2];
        var bInQ = "INSERT INTO [Tbl_TempData] (field1,field2,field3) VALUES ";
        data.forEach(function(rec, index){
            var keys = Object.keys(rec);
            var kLen = keys.length - 1;
            keys.forEach(function(datum,cursor){                
                bInQ += "('" + datum + "','" + rec[datum] + "','" + tName + ")";
                if(cursor < kLen){
                    bInQ += ",";
                }
            });
        });
        module.exports.executeQuery(bInQ,'BULK INSERTION','[Omni_TempSurveyData]',module.exports.processForTempCalc,validateParam);
    },
    module.exports.processForTempCalc: function(validateParam){
        var strSQL = "DELETE FROM [Tbl_TempCalc]";
        util.executeQuery(strSQL,'DELETION','[Tbl_TempCalc]',module.exports.insertIntoTempCalc,validateParam);
    },
    module.exports.insertIntoTempCalc: function(validateParam){
        var strSQL = "INSERT INTO .....";
        //some transformations here from other tables
        util.executeQuery(strSQL,'INSERTION','[Tbl_TempCalcData]');

    },
    module.exports.insertIntoBlankCalc: function(validateParam){
        var strSQL = "INSERT INTO .....";
        util.executeQuery(strSQL,'INSERTION','[Tbl_BlankCalcData]');
        //TODO: return the ajax call
    }

如果我是对的,"modImport.parseFile"函数不返回任何内容,只是在承诺中调用"util.executeQuery"。

所以在这一行中 "var cli = modImport.parseFile(fileName,paramlist(;" cli 没有被值并引发错误;

我认为您应该发送"res.send(cli("作为"modImport.parseFile"的回调作为参数,然后将其发送给"util.executeQuery",或者您应该更改函数

更新:我以这种方式更改了您的代码。所以我不能运行它,但我想它会起作用。 希望对您有所帮助。

router.post('/validate',function(req,res){
    var paramlist = req.body.paramList;
    var fileName = req.body.fileName;
    var GLOBAL.response_function = function(err,data) 
    {
        //here you can do anything with your data or err;
        // like that 
        if (err)
        {
            return res.status(404).send(err.toString());
        }
        else 
        {
            // if your data is json
            return res.status(200).send(JSON.stringify(data));
        }
    };
    modImport.parseFile(fileName,paramlist) ;
});
module.exports.executeQuery = function(strSQL, operationType, tableName, cb, param) {
    logger.log('debug','running query: '+strSQL);
    var request = new sql.Request(connection);
    request.query(strSQL,function(err, recordset) {
        if(err){
            logger.error('ERROR in '+operationType+' ON '+tableName+': '+err);
        }
        logger.info(operationType+' ON '+tableName+' successful!');
        if(cb){
            if (param.is_return_callback)
            {
                cb(err, recordset)
            }
            else 
            {
                cb(param);
            }
        }

    });
},

关键是你通过最后一个应该执行查询的函数发送这个",GLOBAL.response_function,{is_return_callback:true}"

   module.exports.insertIntoTempCalc: function(validateParam){
        var strSQL = "INSERT INTO .....";
        //some transformations here from other tables
        util.executeQuery(strSQL,'INSERTION','[Tbl_TempCalcData]',GLOBAL.response_function, {is_return_callback:true});
    },

最新更新