【问题标题】:Method returns undefined the first time it is called方法在第一次调用时返回 undefined
【发布时间】:2021-11-04 00:39:47
【问题描述】:

我有一种方法可以从数据库中选择不同的值,如下所示:

function displayCategories(res, req) {
    query = `SELECT DISTINCT name FROM product_category;`;
    connection.query(query, function (err, rows) {
        if (err) {
            console.log(err);
            res.render("home");
            throw err;
        } else {
            session = req.session;
            session.categories = rows[0];
        }
    });
}

然后我有一个带有方法 POST 和操作 /categories 的按钮

点击按钮时调用displayCategories,如下:

router.post('/categories', function (req, res) {
    displayCategories(res, req);
    if (session.categories === undefined) {
        console.log("categories is undefined");
    } else {
        console.log("categories is defined");
        console.log(session.categories);
    }
})

我添加了一些控制台日志用于测试目的。我遇到的问题是我第一次单击按钮时,它返回未定义。每次我再次单击它时,它都会为session.categories 打印正确的数据,如下所示:

这个问题有简单的解决方法吗?

【问题讨论】:

    标签: javascript mysql node.js express


    【解决方案1】:

    代码正在调用displayCategories,就好像它是同步的,但它正在运行带有回调的异步代码。

    对此有多种可能的解决方案,但其中之一是使用 Promises,如下所示:

    const displayCategories = (res, req) => new Promise((resolve, reject) => {
        // you are not declaring query in this scope, that makes it global
        query = `SELECT DISTINCT name FROM product_category;`
        connection.query(query, function (err, rows) {
            if (err) {
                console.error(err)
                res.render("home")
                reject(err)
            } else {
                session = req.session
                session.categories = rows[0]
                resolve()
            }
        })
    })
    

    另一部分带有异步功能

    router.post('/categories', async function (req, res) {
        await displayCategories(res, req);
        if (session.categories === undefined) { // session is not declared
            console.log("categories is undefined");
        } else {
            console.log("categories is defined");
            console.log(session.categories); // session is not declared
        }
    })
    

    但这只是为了让您的问题消失,如果您想进一步改进代码,您可以只负责使用控制器操作处理请求和响应,并使用其他功能来获取您想要的数据,隔离其责任:

    const getCategories = () => new Promise((resolve, reject) => {
      const query = `SELECT DISTINCT name FROM product_category;`
      connection.query(query, (err, rows) => {
        if (err) return reject(err)
    
        resolve(rows)
      })
    })
    
    router.post('/categories', async function (req, res) {
      try {
        req.session.categories = await getCategories();
    
        if (req.session.categories === undefined) {
            console.log("categories is undefined");
        } else {
            console.log("categories is defined", req.session.categories);
            console.log();
        }
      } catch(e) {
        console.error(e)
        res.render("home")
      }
    })
    

    【讨论】:

    • 感谢您的回复,完美运行:)
    猜你喜欢
    • 2018-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-30
    • 1970-01-01
    相关资源
    最近更新 更多