未处理的承诺被拒在哪里?我该如何避免呢?

时间:2018-06-29 14:22:12

标签: javascript sql-server node.js promise

与Node和mssql一起使用,以拉取对五个不同数据库的查询以相互进行重复数据删除,并合并为一个更加统一的架构。

我的流程遵循以下算法:

通过调用此函数创建共享池:

const getPoolConnection = async () => {
  try {
    let pool = await mssql.connect(`mssql://${username}:${password}@${server}/`);
    return pool;
  } catch (err) {
    console.error(err);
  }
};

此函数创建池并将其返回给调用函数。将usernamepasswordserver导入到该文件并确定其范围。

然后,我们查询每个数据库,并将结果分配给对象的属性。这是通过forEach循环完成的:

lists.forEach(list => {
  fullData[list] = db.queryDatabase(pool, customers[list].query).catch(err => console.error(err));
})

调用此函数:

const queryDatabase = async (pool, query) => {
  try {
    let result = await pool.request().query(query);
    // console.log(result);
    return result.recordset, pool;
  } catch (err) {
    console.error(err);
  }
};

现在为了防止在所有数据库调用返回数据之前进行后处理,我将整个调用集包装在主Promise.all()文件中的index.js调用中。这是调用函数:

const { customers } = require('./query');
const util = require('./util');
const db = require('./db');

fullData = {};

(async () => {
  let pool = await db.getPoolConnection();
  let lists = Object.keys(customers);
  Promise.all(
    lists.forEach(list => {
      fullData[list] = db.queryDatabase(pool, customers[list].query).catch(err => console.error(err));
    })
  )
    .then(results, pool => {
      console.dir(results);
      db.closePoolConnection(pool);
    })
    .catch(err => console.error(err));
})();

我不理解的是尝试调试应用程序时发生的错误:

  

(节点:18908)UnhandledPromiseRejectionWarning:TypeError:无法读取   未定义警告的属性'Symbol(Symbol.iterator)'。js:18       在Function.all()       在c:\ Users \ rutherfordc \ Documents \ GitHub \ migration-plus \ index.js:10:11       在       在process._tickCallback(内部/进程/next_tick.js:188:7)(节点:18908)UnhandledPromiseRejectionWarning:未处理的承诺   拒绝。该错误是由抛出异步内部引起的   没有捕获块或拒绝承诺   未使用.catch()处理。 (拒绝ID:1)warning.js:18   (节点:18908)[DEP0018]弃用警告:未处理的承诺   不推荐使用。将来,应承诺拒绝   未处理将以非零退出终止Node.js进程   码。 warning.js:18(节点:18908)UnhandledPromiseRejection警告:   ReferenceError:结果未定义警告。js:18       在c:\ Users \ rutherfordc \ Documents \ GitHub \ migration-plus \ index.js:15:11       在       在process._tickCallback(内部/进程/next_tick.js:188:7)(节点:18908)UnhandledPromiseRejectionWarning:未处理的承诺   拒绝。该错误是由抛出异步内部引起的   没有捕获块或拒绝承诺   未使用.catch()处理。 (拒绝ID:2)

2 个答案:

答案 0 :(得分:1)

Promise.all()需要一个数组。因此,您可以执行以下操作:

fullData = [];

(async () => {
  let pool = await db.getPoolConnection();
  let lists = Object.keys(customers);
  lists.forEach(list => {
    fullData.push(db.queryDatabase(pool, customers[list].query).catch(err => console.error(err));
  }));

  Promise.all(fullData)
    .then((results, pool) => {
      console.dir(results);
      db.closePoolConnection(pool);
    })
    .catch(err => console.error(err));
})();

更新

正如J. Pichardo在回答中所建议的那样,如果有多个参数,则应将参数括在括号中。
Documentation

答案 1 :(得分:1)

错误是非逻辑的,但是语法错误,主要功能的以下几行

.then(results, pool => {
  console.dir(results);
  db.closePoolConnection(pool);
})

箭头函数的参数应该用括号括起来,例如:

.then((results, pool) => {
  console.dir(results);
  db.closePoolConnection(pool);
})
  

ReferenceError:结果未定义

因此,then正在寻找一个results变量,由于它崩溃时是一个async函数,因此它将是一个UnhandledPromiseRejection

更新:

正如另一个答案所说,Promise.all会收到多个承诺或一系列承诺,因此您可以执行以下操作:

var fullData = lists.map(list => db.queryDatabase(pool, customers[list].query).catch(err => console.error(err)));

Promise.all(fullData).then(...)