将Async / Await与node-postgres结合使用

时间:2018-12-24 08:13:20

标签: node.js postgresql node-postgres

我正在使用node-postgres查询我的数据库,想知道如何使用async / await并正确处理错误

我的用法示例是一个非常简单的查询

const { Pool } = require('pg');

let config;
if (process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'staging') {
  config = { connectionString: process.env.DATABASE_URL, ssl: true };
} else {
  config = {
    host: 'localhost',
    user: 'myuser',
    database: 'mydatabase',
  };
}

const pool = new Pool(config);

async function getAllUsers() {
  let response;
  try {
    response = await pool.query('select * FROM users');
  } catch (error) {
    throw error;
  }
  return response.rows;
}

然后在我的routes.js中拥有

app.get('/all_users', async (req, res) => {
  const users = await queries.getAllUsers();
  console.log(users); // returns all users fine
});

到目前为止,这是我的理解,但我认为我无法正确处理此问题,因为涉及到错误,我的应用将冻结并抛出UnhandledPromiseRejectionWarning。因此,例如,如果我提供了不正确的表格

async function getAllUsers() {
  let response;
  try {
    response = await pool.query('select * FROM notable');
  } catch (error) {
    throw error;
  }
  return response.rows;
}

UnhandledPromiseRejectionWarning: error: relation "notable" does not exist

该应用将在30秒后崩溃,并且我没有很好地处理此错误

有人可以指出我在这里想念的吗?

1 个答案:

答案 0 :(得分:2)

async函数或Promise抛出未捕获的错误时,或者捕获程序也抛出时,例如您的

throw error;

这意味着该函数的调用方将面临被拒绝的Promise处理。如果您在调用方中使用await,则还必须在调用方中使用try/catch才能正确捕获错误:

app.get('/all_users', async (req, res) => {
  try {
    const users = await queries.getAllUsers();
    console.log(users);
  } catch(e) {
    // handle errors
  }
});

无需在使用者中使用try/catch来解决错误的另一种方法是不要throw catch中的错误:

async function getAllUsers() {
  let response;
  try {
    response = await pool.query('select * FROM users');
    return response.rows;
  } catch (error) {
    // handle error
    // do not throw anything
  }
}

但这会使消费者更难知道何时出现错误。

在这种情况下,async / await / try / catch的构造会增加很多语法上的噪音,而对IMO却没有太大的好处-目前,您可能会考虑改用普通的Promises:

const getAllUsers = () => pool.query('select * FROM users')
  .then(response => response.rows);

// and:
app.get('/all_users', (req, res) => {
  queries.getAllUsers()
    .then((users) => {
      console.log(users);
    })
    .catch((err) => {
      // handle errors
    });
});

asyncawait在您希望在代码中显得平淡一些的.then时发光。如果只有一个.then,则IMO将其转换为async / await语法并没有太大好处。当然,这取决于您。