【问题标题】:Moving code to an exported function results in TypeError: Converting circular structure to JSON将代码移动到导出的函数会导致 TypeError:将循环结构转换为 JSON
【发布时间】:2020-05-08 23:22:57
【问题描述】:

我正在使用 expressmysql 包来测试查询。

我有这个代码:

connection.connect();

connection.query('SELECT 1 + 1 AS solution', (error, results) => {
  if (error) {
    connection.end();
    console.log('error');
    throw error;
  }
  connection.end();
  console.log(results);
  return results;
});

而且效果很好。但是当我将它移动到另一个文件并尝试像这样导出它时:

query.js

const connection = require('../config/connection');

connection.connect();

module.exports = async (query) => connection.query(query, (error, results) => {
  console.log(query);
  if (error) {
    // connection.end();
    console.log('error');
    throw error;
  }
  // connection.end();
  console.log(results);
  return results;
});

app.js

try {
  const queryResult = await query('SELECT 1 + 1 AS solution');
  console.log(queryResult, 2);
  res.send(queryResult);
} catch (err) {
  console.log(err);
}

我收到此错误:

TypeError: Converting circular structure to JSON
at JSON.stringify (<anonymous>)
at stringify (C:\Users\aironsid\Documents\tatooify\server\node_modules\express\lib\response.js:1119:12)
at ServerResponse.json (C:\Users\aironsid\Documents\tatooify\server\node_modules\express\lib\response.js:260:14)
at ServerResponse.send (C:\Users\aironsid\Documents\tatooify\server\node_modules\express\lib\response.js:158:21)
at app.get (C:\Users\aironsid\Documents\tatooify\server\app.js:44:9)
at process._tickCallback (internal/process/next_tick.js:68:7)

同样在控制台日志中,我得到一个大对象,后跟数字 2,然后我得到 errthe ``或者,然后我得到查询值,然后是结果。像这样:

Big object 2

error

SELECT 1 + 1 AS solution

[ RowDataPacket { solution: 2 } ]

所以这告诉我我的代码是异步运行的。从两个文件中删除 async/await 不会改变任何内容。所以我的代码首先运行app.js 代码,然后运行query.js 代码,这需要一些时间。但为什么?我怎样才能让它等待? connection.query() 确实返回承诺。

【问题讨论】:

    标签: javascript mysql node.js express asynchronous


    【解决方案1】:

    问题是您的async 函数没有等待查询完成。

    它应该返回一个在查询完成时解析的promise,而是返回立即解析为函数connection.query()的返回值的promise。

    您应该将其更改为:

    module.exports = (query) => {
    
        return new Promise(resolve => 
            connection.query(query, (error, results) => {
              console.log(query);
              if (error) {
                // connection.end();
                console.log('error');
                throw error;
              }
              // connection.end();
              console.log(results);
              resolve(results);
            })
        );
    
    }
    

    省略注释行和更短的语法:

    module.exports = (query) => new Promise((resolve, reject) => 
      connection.query(query, (error, results) => {
        if (error) return reject(error);
    
        resolve(results);
      })
    );
    

    甚至更短:

    module.exports = (query) => 
      new Promise((resolve, reject) => 
        connection.query(query, (error, results) => 
          error ? reject(error) : resolve(results)
      )
    );
    

    澄清:您的 async 关键字没有任何作用,因为它的作用是允许您在其函数中使用 await 并将您返回的任何内容包装到一个 Promise 中。

    您没有使用任何awaits,并立即通过 lambda 函数返回结果。

    请注意,您从回调返回的 return 语句传递给了 connection.query 函数,而不是从 main 函数。

    【讨论】:

      猜你喜欢
      • 2020-12-02
      • 1970-01-01
      • 2017-06-29
      • 2018-10-05
      • 2016-01-22
      • 2019-01-05
      • 1970-01-01
      • 1970-01-01
      • 2023-01-31
      相关资源
      最近更新 更多