为什么在调用数据库调用时未定义我的参数?

Why is my argument not defined when invoking a DB call?

我正在尝试通过 GraphQL 解析器 return Postgres DB 查询。出于某种原因,result 在我(有意)查询行中不存在的 ID 时返回为未定义。当我控制台记录它时,result 总是按预期返回:

result = {
 rows: [],
 ...
}

但是,当我 运行 它并进行查询时,或者当我使用 node inspect index.js 并让它 运行 直到调试器时,它似乎无法识别 result 甚至被定义。当我在 Node 中 运行 console.log(result) 遇到调试器时,出现此错误:

debug> console.log(result)
REPL2:1
console.log(result)
            ^

Uncaught ReferenceError: result is not defined
    at REPL2:1:13
    at Script.runInContext (node:vm:139:12)
    at Object.runInContext (node:vm:289:6)
    at REPLServer.controlEval (node:internal/debugger/inspect_repl:578:25)
    at bound (node:domain:421:15)
    at REPLServer.runBound [as eval] (node:domain:432:12)
    at REPLServer.onLine (node:repl:898:10)
    at REPLServer.emit (node:events:527:28)
    at REPLServer.emit (node:domain:475:12)
    at [_onLine] [as _onLine] (node:internal/readline/interface:424:12)

当我从 Playground 运行 查询时,我得到了这个错误:

/Users/user/Projects/geolocatr_api/db/queries/user.queries.js:21
          id: user.id,
                   ^

TypeError: Cannot read properties of undefined (reading 'id')
    at /Users/user/Projects/geolocatr_api/db/queries/user.queries.js:21:20
    at Query.<anonymous> (/Users/user/Projects/geolocatr_api/node_modules/pg-pool/index.js:417:18)
    at Query.handleReadyForQuery (/Users/user/Projects/geolocatr_api/node_modules/pg/lib/query.js:138:12)
    at Client._handleReadyForQuery (/Users/user/Projects/geolocatr_api/node_modules/pg/lib/client.js:290:19)
    at Connection.emit (node:events:527:28)
    at /Users/user/Projects/geolocatr_api/node_modules/pg/lib/connection.js:114:12
    at Parser.parse (/Users/user/Projects/geolocatr_api/node_modules/pg-protocol/dist/parser.js:40:17)
    at Socket.<anonymous> (/Users/user/Projects/geolocatr_api/node_modules/pg-protocol/dist/index.js:11:42)
    at Socket.emit (node:events:527:28)
    at addChunk (node:internal/streams/readable:324:12)

Node.js v18.0.0
error Command failed with exit code 1.

我真的不确定为什么我的控制台日志似乎看到有东西在那里,但 Node 却没有。否则,当传入 table 中存在的 ID 时,它会按预期工作。

代码:

// Resolver

  Query: {
    user: ( _, { id } ) => {
      console.log({id}); // Node recognizes this as the correct number
      return getUserById(id);
    },
  },


// DB Query Function

const getUserById = (id) => {
  return new Promise(function(resolve, reject) {
    db.query(
      `
        SELECT id, first_name, email, phone
        FROM users
        WHERE id = ;
      `,
      [id],
      function(err, result) {
        // debugger; // Result comes back as not defined
        if (!result.rows) { // Will not run this if block
          console.log(result.rows);
          reject("Could not find user.");
        }
        if (err) reject(err);
        const user = rows[0];

        resolve({
           id: user.id,
           firstName: user.first_name,
           email: user.email,
           phone: user.phone,
        });
      }
    );
  });
};

通常对于那些 (err, result) => { ... } 回调,您首先检查 err ,因为如果它是 truthy,那么第二个参数很有可能不会被定义。

您还应该 return 在检测到错误以防止回调的其余部分执行后。

仅供参考,node-postgresl 原生支持承诺,因此无需显式创建承诺。下面我将您的代码翻译成异步函数以利用它。

const getUserById = async (id) => {
  const { rows } = await db.query({
    text: "SELECT id, first_name as firstName, email, phone FROM users WHERE id = ",
    values: [id],
  });

  // `rows` is always an array so check the length
  if (rows.length !== 1) {
    throw new Error(`Could not find user by id [${id}]`);
  }

  return rows[0];
};