NodejS .then(promise)调用者在异步功能完成之前得到了不好的结果 [英] NodejS .then (promise) Caller gets bad results before async function finishes

查看:57
本文介绍了NodejS .then(promise)调用者在异步功能完成之前得到了不好的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我在这里提出的问题的重新启动:然后/捕获NodeJS函数中似乎正在捕获函数外部的代码我改变了很多次,尽管这很相似,但我认为这基本上是一个不同的问题.

This is a reboot of the question I asked here: NodeJS then/catch in a function seems to be catching code outside the function I changed so many times, I think this is basically a different question, although similar.

我的NodeJS代码:

My NodeJS code:

var express = require('express');
var app = express();

// config for your database
var config = {
    user: 'ReadOnlyUser1',
    password: 'Password1',
    server: 'localhost\\SQLEXPRESS', 
    database: 'StudentsOld' 
};

var lookupStudentId = 31; 


const sql = require('mssql');

var connPool = new sql.ConnectionPool(config);

function getStudent(studentID) 
{
    console.log("getStudent"); 

    sql.connect(config).then(pool => {
        // Query 
        return pool.request()
        .input('input_parameter', sql.Int, studentID)
        .query('select student_firstname, student_lastname from students where student_id = @input_parameter')
    }).then(function(result) {
        console.log("getStudent:then(result=>"); 
        console.dir(result);
        sql.close(); 
        //return result; 
    })
    .catch(err => {
        // ... error checks 
        console.log("DB Error1: " + err); 
    })

    sql.on('error', err => {
        // ... error handler 
        console.log("DB Error2: " + err); 
    })
}


app.get('/student', function(request, response){
    console.log('Neal Test1 - start app.get for /student lookupStudentId = ' + lookupStudentId); 
    getStudent(lookupStudentId)
        .then (function(recordset)  {  /* this is line 82 of the error */
            objType = Object.prototype.toString.call(recordset);
            console.log('Back from getStudent objType=' + objType  ); 
            console.dir('recordSet=' + recordSet); 
            response.status(200).send(recordset); 
        })
        .catch (function(err) {
            objType = Object.prototype.toString.call(recordset);
            console.log('ERR: Back from getStudent objType=' + objType  ); 
            console.log("error400=" + err); 
            console.log("empty test=" + Object.keys(err).length); 
            response.status(400).send(err);
        })
    return;
});

app.listen(3000, function () {
    console.log('Express server is listening on port 3000');
});

Console.Log:

Console.Log:

Express server is listening on port 3000
Neal Test1 - start app.get for /student lookupStudentId = 31
getStudent
TypeError: Cannot read property 'then' of undefined
    at C:\Software\nodejs\wisdomcalls\indexPromises.js:82:9
    at Layer.handle [as handle_request] (C:\Software\nodejs\wisdomcalls\node_modules\express\lib\router\layer.js:95:5)
    at next (C:\Software\nodejs\wisdomcalls\node_modules\express\lib\router\route.js:137:13)
    at Route.dispatch (C:\Software\nodejs\wisdomcalls\node_modules\express\lib\router\route.js:112:3)
    at Layer.handle [as handle_request] (C:\Software\nodejs\wisdomcalls\node_modules\express\lib\router\layer.js:95:5)
    at C:\Software\nodejs\wisdomcalls\node_modules\express\lib\router\index.js:281:22
    at Function.process_params (C:\Software\nodejs\wisdomcalls\node_modules\express\lib\router\index.js:335:12)
    at next (C:\Software\nodejs\wisdomcalls\node_modules\express\lib\router\index.js:275:10)
    at expressInit (C:\Software\nodejs\wisdomcalls\node_modules\express\lib\middleware\init.js:40:5)
    at Layer.handle [as handle_request] (C:\Software\nodejs\wisdomcalls\node_modules\express\lib\router\layer.js:95:5)
getStudent:then(result=>
{ recordsets: [ [ [Object] ] ],
  recordset:
   [ { student_firstname: 'Jonah                ',
       student_lastname: 'Hill                    ' } ],
  output: {},
  rowsAffected: [ 1 ] }

所以这告诉我的是,调用例程的.then语句正在运行,并且可能在函数仍试图获取其数据库连接的同时获取了未定义".

So what this tells me is that the .then statement of the calling routine is running and getting the "undefined" probably while the function is still trying to get it's database connection.

如何保持异步最佳实践/模型,并在检索到数据后能够正确处理我的数据?

How do I keep the Async best practice/model, and be able to handle my data properly after it has been retrieved?

我读到这个问题:节点在异步功能完成之前退出在目标上-但这就是答案,我如何将其包装在我的SQL请求中?我要尝试一下,如果知道了,我会在这里发布答案.

I read this question: Node exits before async function completes which seems on target - but if that's the answer, how would I wrap that around my SQL request? I'm going to try it, and if I get it, I will post answer here.

修订2

function getStudent(studentID) 
{
    console.log("---------getStudent"); 

    sql.on('error', err => {
        // ... error handler 
        console.log("DB Error2: " + err); 
    })

    return sql.connect(config).then(pool => {
            // Query 
            return pool.request()
            .input('input_parameter', sql.Int, studentID)
            .query('select student_firstname, student_lastname from students where student_id = @input_parameter')
        }).then(function(result) {
            console.log("getStudent:then(result=>"); 
            console.dir(result);
            sql.close(); 
            return result; 
        })
        .catch(err => {
            // ... error checks 
            console.log("DB Error1: " + err); 
        })

}


app.get('/student', function(request, response){
    console.log('==================Neal Test1 - start app.get for /student lookupStudentId = ' + lookupStudentId+ '======================='); 

    //process.on('unhandledRejection', r => function(){});

    getStudent(lookupStudentId)
        .then (function(recordset)  {
            console.log('Back from getStudent'); 
            objType = Object.prototype.toString.call(recordset);
            console.log('objType=' + objType  ); 
            console.dir('recordSet=' + recordSet); 
            response.status(200).send(recordset); 
        })
        .catch (function(err) {
            objType = Object.prototype.toString.call(recordset);
            console.log('ERR: Back from getStudent objType=' + objType  ); 
            console.log("error400=" + err); 
            console.log("empty test=" + Object.keys(err).length); 
            response.status(400).send(err);
        })
    return;
});

控制台日志:

    ==================Neal Test1 - start app.get for /student lookupStudentId = 31=======================
    ---------getStudent
    getStudent:then(result=>
    { recordsets: [ [ [Object] ] ],
      recordset:
       [ { student_firstname: 'Jonah                ',
           student_lastname: 'Hill                    ' } ],
      output: {},
      rowsAffected: [ 1 ] }
Back from getStudent
objType=[object Object]
(node:26212) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): ReferenceError: recordset is not defined

此时,程序似乎已挂起.永不返回浏览器.

At this point the program seems to hang. Never goes back to browser.

推荐答案

getStudent 不返回任何内容(因此为 undefined ),因此它没有然后属性.

getStudent does not return anything (so undefined), so it does not have the then property.

它应该返回一个承诺,因此请在此处添加 return :

It should return a promise, so add return here:

return sql.connect(config).then(pool => {

...,然后将 sql.on 调用移至该返回之前.

... and move the sql.on call before that return.

第二,取消注释此行:

// return result;

因为需要沿着承诺链传递结果.您将在 app.get 回调函数中以 recordset 的形式获取其值.

Because that result needs to be passed along the promise chain. You'll fetch its value as recordset in the app.get callback function.

这篇关于NodejS .then(promise)调用者在异步功能完成之前得到了不好的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆