【问题标题】:promise returning undefined node js承诺返回未定义的节点js
【发布时间】:2018-10-11 02:24:08
【问题描述】:

我有一个函数可以连接到 sql 数据库,对其进行查询,将结果格式化为 html 表并返回 html 变量:

function getData() {
    return new Promise((resolve, reject) => {
        var sql = require("mssql");
        var dbConfig = {
            server: "server",
            database: "db",
            user: "user",
            password: "pw"
        }
        var conn = new sql.Connection(dbConfig);
        var req = new sql.Request(conn);
        conn.connect(function (err) {
            if (err) {
                console.log(err);
                reject(err);
                return;
            }
            req.query("SELECT * FROM table",
                (err, recordset) => {
                    // Here we call the resolve/reject for the promise
                    try {
                        // If the results callback throws exception, it will be caught in 
                        // the catch block
                        resolve(resultsCallback(err, recordset));
                    }
                    catch (e) {
                        reject(e);
                    }
                }
            );

            conn.close();
        });
    })
}

function resultsCallback(err, recordset) {
    var tableify = require('tableify');
    if (err) {
        console.log(err);
        throw err;
    }
    else {
        var html = tableify(recordset);
        html = html.replace('<table>', '');
        html = html.replace('</table>', '');
        return html;
    }
};

我这样称呼它:

getData().then((data)=>{console.log("Table data:",data);})
         .catch((error)=>{console.log("ERROR LOADING SQL:",error);})

但是,由于某种原因,输出是:Table Data: undefined

我不确定为什么会这样。我返回的数据是否正确?

【问题讨论】:

  • 您是否检查过recordset 不是undefined
  • 不,它不是undefined。我可以将记录集的内容写入 console.log
  • 看起来return html应该resolveing 之前运行的行,并且无论html 是什么都应该是data 参数。但是如果你能够html = html.replace('&lt;/table&gt;', ''); 而不抛出错误,那么应该定义html。您是否尝试记录这些行以查看它们是否按预期运行和填充?
  • 尝试在req.query() 完成后关闭连接。
  • 我已经把所有external 函数(conn.* req.* tableify)都搞砸了,你发布的代码没有出现问题 - @987654339 的内容是什么@ 紧跟在var html = tableify(recordset); 之后

标签: javascript sql-server node.js npm promise


【解决方案1】:

我认为您的 resultsCallback 不必要地与错误处理纠缠在一起

我试图用一些现代风格来清理你的例子,希望它可以帮助你

const sql = require("mssql")
const tableify = require("tableify")

/**
* FORMAT RESULTS
*  - format sql records as html
*  - returns a string of html
*/
function formatResults(records) {
  return tableify(records)
    .replace("<table>", "")
    .replace("</table>", "")
}

/**
* GET DATA
*  - query records from a database
*  - returns a promised string of html
*/
async function getData({db, table}) {

  // open the sql connection pool
  const pool = await sql.connect(db)

  // query the database and format the results
  try {
    const results = await pool.request()
      .input("tablename", table)
      .query(`SELECT * from @tablename`)
    return formatResults(results)
  }

  // rethrow query errors
  catch (error) {
    error.message = `getData sql query error: ${error.message}`
    throw error
  }

  // always close the connection
  finally {
    pool.close()
  }
}

// USAGE EXAMPLE BELOW
;(async() => {

  const data = await getData({
    db: {
      server: "server",
      database: "db",
      user: "user",
      password: "pw"
    },
    table: "table"
  })

  console.log(data)

})().catch(error => console.error(error))

【讨论】:

  • getData 设为异步函数毫无意义——它已经返回了一个承诺。另外,你不能像这样在顶层使用await
  • 在异步函数方面,关键字async 始终存在是件好事——顶级等待已修复
  • 您可以完全摆脱 Promise(使用 util.promisify)和回调。你也忘了connection.close(),这可以很容易地在 try-catch-finally 中使用 await 来完成。 Checkout this gist
  • 添加了connection.close() 电话
  • 这实际上解决了什么问题? OP 的代码有什么问题?
猜你喜欢
  • 2019-07-14
  • 2015-09-27
  • 1970-01-01
  • 2019-03-07
  • 1970-01-01
  • 2017-07-23
  • 1970-01-01
相关资源
最近更新 更多