【问题标题】:Where is the unhandled promise rejection? How can I avoid it?未处理的承诺拒绝在哪里?我怎样才能避免它?
【发布时间】:2018-12-08 18:34:59
【问题描述】:

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

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

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

【问题讨论】:

    标签: javascript sql-server node.js promise


    【解决方案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

    【讨论】:

    • 好的!让我们看看实际情况!立即测试。
    【解决方案2】:

    错误是非逻辑但语法错误,主函数中的以下几行

    .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(...)
    

    【讨论】:

      猜你喜欢
      • 2016-08-18
      • 1970-01-01
      • 2013-07-24
      • 2021-04-01
      • 2016-11-24
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多