Promise.catch() 无法捕获 Promise 中的错误

问题描述 投票:0回答:1

我正在尝试检查许多条件,如果其中一个条件为真,我想继续执行某个回调函数。否则,我想继续使用不同的回调函数。一些伪代码可能如下所示:

if (condition_1 OR condition_2 OR condition_3) {
    on_satisfied()
} else {
    on_unsatisfied()
}

但是,检查每个条件都需要一段时间(例如,可能需要数据库查询),所以我想异步检查它们。我还知道,如果其中任何一个返回 TRUE,则我已经满足了我的条件,因此想停止执行并忘记其余条件。为了做到这一点,我想在第一个响应中使用here描述的“肮脏技巧”:抛出一个将在父函数中处理的错误(位于此处的承诺内)

// the function we call if at least one condition is satisfied
function on_satisfied() {
    console.log("At least one condition satisfied")
}

// the function we call if no conditions are satisfied
function on_unsatisfied() {
    console.log("No conditions satisfied")
}

// a sample condition-checking function
async function check_lessthan_5(to_check, callback_if_not) {
    // using a timeout to simulate "slow" checking of conditions;
    // the slow checking could be a result of e.g. database queries
    await new Promise(r => setTimeout(r, 2000));
    if (to_check < 5) {
        // throw this error in hopes of terminating parent function,
        // because it is sufficient for one condition to be met 
        // in order for the whole OR-joined expression to be true (we want to stop execution of the parent function)
        throw Error("value < 5")
    }
    return false
}

const all_cond_checker = new Promise((resolve, reject) => {
    // store all the resulting promises, 
    // so when they all resolve we know that no conditions were satisfied
    var conditions_list = []
    // check all the conditions. In this case, we want to see if any of these numbers is >= 5
    for (var i=0; i < 10; ++i) {
        // push a resulting promise into the list, we can check later that it resolves
        // if the condition is met, terminate this function by propagating error up
        conditions_list.push(check_lessthan_5(i)).catch((error) => {resolve()})
    }
    // once all the promises return, us getting here implies no errors were thrown 
    // which implies no conditions satisfied
    Promise.all(conditions_list).then(reject)
});

问题是,promise 中的

.catch()
似乎没有捕获错误!运行代码,我得到以下结果:

$ node async_test.js
No conditions satisfied
/home/daniel/Signoff-again/node-experiments/async_test.js:20
            throw Error("value >= 5")
            ^

Error: value < 5
    at Timeout._onTimeout (/home/daniel/Signoff-again/node-experiments/async_test.js:20:19)
    at listOnTimeout (node:internal/timers:557:17)
    at processTimers (node:internal/timers:500:7)

我对这些结果的解释是,由于某种原因,.catch() 被完全跳过,错误未被处理,

for
循环被破坏,然后 Promise.all() 被执行(因为所有 5 个
conditions_list
中的 Promise 已解决),因此调用
on_unsatisfied
函数。相反,我想要/期望的是第一个
on_satisfied
返回后立即调用
check_lessthan_5
函数。

所以问题是:为什么

catch()
在这里似乎不起作用?另外,有更好的方法吗?

提前致谢。

我希望一旦满足第一个条件,返回的错误就会被

.catch()
中的
all_cond_checker
捕获,然后调用
on_satisfied
。我不希望错误一直“传播”出去并在控制台中报告。

预期的控制台输出是:

$ node async_test.js
At least one condition satisfied
javascript node.js asynchronous promise catch-block
1个回答
0
投票

你的捕获物放错了地方

async function check_lessthan_5(to_check) {
  await new Promise((r) => setTimeout(r, 2000));
  if (to_check < 5) {
    throw Error('value < 5');
  }
  return false;
}

const all_cond_checker = new Promise((resolve, reject) => {
  var conditions_list = [];
  for (var i = 0; i < 10; ++i) {
    conditions_list.push(check_lessthan_5(i));
  }
  Promise.all(conditions_list)
    .then((r) => resolve(r))
    .catch((err) => reject(err));
});

all_cond_checker
  .then((r) => console.log(r))
  .catch((err) => console.log(err.message));

© www.soinside.com 2019 - 2024. All rights reserved.