You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js循环更新PostgreSQL表数据失败,单条更新正常求解决

问题原因与解决方案

核心问题

你的代码里有两个关键问题导致循环更新失败:

  1. forEach不等待异步操作:forEach会一次性触发所有异步的updateEdition调用,但不会等待这些异步任务完成,就直接执行后面的await pool.end(),导致数据库连接提前关闭,更新请求还没执行完就被中断了。
  2. 连接提前关闭:当所有updateEdition的异步操作还在后台排队时,连接已经被关闭,PostgreSQL会终止未完成的请求,自然无法更新成功。

修复方案

你可以用两种方式解决,选一种就行:

方案一:用for...of循环(推荐,更直观)

把forEach换成for...of,它会等待每个异步操作完成后再执行下一次循环,确保所有更新都完成后再关闭连接:

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

const credentials = {
  user: 'postgres',
  host: 'localhost',
  database: 'dev',
  password: 'secret',
  port: 5432,
};

const pool = new Pool(credentials);

async function getEditions() {
  const sql = `SELECT * FROM editions`;
  return pool.query(sql);
}

async function updateEdition(id, slug) {
  const values = [id, slug];
  try {
    const text = `UPDATE editions SET slug = $2 WHERE id = $1`;
    await pool.query(text, values);
    console.log(`Updated edition ${id}`);
  } catch (error) {
    console.error(`Failed to update edition ${id}:`, error);
  }
}

(async () => {
  const getEditionsResult = await getEditions();

  // 替换forEach为for...of
  for (const e of getEditionsResult.rows) {
    await updateEdition(e.id, slug(e.name));
  }

  await pool.end();
  console.log('All updates completed, connection closed');
})();

方案二:用Promise.all批量处理

把所有更新任务收集成Promise数组,用Promise.all等待全部完成后再关闭连接:

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

const credentials = {
  user: 'postgres',
  host: 'localhost',
  database: 'dev',
  password: 'secret',
  port: 5432,
};

const pool = new Pool(credentials);

async function getEditions() {
  const sql = `SELECT * FROM editions`;
  return pool.query(sql);
}

async function updateEdition(id, slug) {
  const values = [id, slug];
  try {
    const text = `UPDATE editions SET slug = $2 WHERE id = $1`;
    await pool.query(text, values);
    console.log(`Updated edition ${id}`);
  } catch (error) {
    console.error(`Failed to update edition ${id}:`, error);
  }
}

(async () => {
  const getEditionsResult = await getEditions();

  // 收集所有更新任务的Promise
  const updatePromises = getEditionsResult.rows.map(e => updateEdition(e.id, slug(e.name)));
  // 等待所有Promise完成
  await Promise.all(updatePromises);

  await pool.end();
  console.log('All updates completed, connection closed');
})();

补充说明

  • 单条更新正常是因为此时await pool.end()会等待单条更新完成后再执行,不会提前关闭连接。
  • 用for...of适合需要串行执行更新的场景,Promise.all适合并行执行(效率更高,但要注意数据库连接池的并发限制)。

内容的提问来源于stack exchange,提问作者Mantoze

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 21:36:26