首页 文章

未处理的承诺拒绝在哪里?我怎么能避免呢?

提问于
浏览
0

使用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);
  }
};

现在为了在所有数据库调用返回数据之前保持后处理不存在,我将整个调用集包装在主 index.js 文件的 Promise.all() 调用中 . 这是调用功能:

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));
})();

我不明白的是在尝试调试应用程序时出现此错误:

(node:18908)UnhandledPromiseRejectionWarning:TypeError:无法在c:\ Users \ rutherfordc \ Documents \ GitHub \ migration-plus \的Function.all()中读取未定义warning.js:18的属性'Symbol(Symbol.iterator)' index.js:10:11 at at process._tickCallback(internal / process / next_tick.js:188:7)(node:18908)UnhandledPromiseRejectionWarning:未处理的promise promise rejection . 此错误源于通过抛出异步函数而没有catch块,或者拒绝未使用.catch()处理的promise . (rejection id:1)warning.js:18(node:18908)[DEP0018]弃用警告:不推荐使用未处理的拒绝承诺 . 将来,未处理的承诺拒绝将使用非零退出代码终止Node.js进程 . warning.js:18(node:18908)UnhandledPromiseRejectionWarning:ReferenceError:结果未定义warning.js:18 at c:\ Users \ rutherfordc \ Documents \ GitHub \ migration-plus \ index.js:15:11 at at process . _tickCallback(internal / process / next_tick.js:188:7)(node:18908)UnhandledPromiseRejectionWarning:未处理的承诺拒绝 . 此错误源于通过抛出异步函数而没有catch块,或者拒绝未使用.catch()处理的promise . (拒绝ID:2)

2 回答

  • 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(...)
    
  • 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));
    })();
    

    Update:

    正如J. Pichardo在他的回答中建议的那样,在多个参数的情况下,参数应该括在括号中 .
    Documentation

相关问题