javascript 常见异常捕获

127 阅读1分钟

1、try-catch

try-catch 主要用于捕获同步异常、无法捕获到异步异常, 原因是因为:当异步函数抛出异常时,对于宏任务而言,执行函数时已经将该函数推入栈,此时并不在 try-catch 所在的栈,所以 try-catch 并不能捕获到错误。对于微任务而言,比如 promise,promise 的构造函数的异常只能被自带的 reject 也就是.catch 函数捕获到

同步异常
try {
  throw new Error('1')
 } catch(error) {
  console.log('异常:',error) // 异常: Error: 1
 }
// async await:异步转同步
const p = (rect) => {
  return new Promise((resolve, reject) => {
    if (rect) resolve("成功");
    else reject("失败");
  });
};

const fn = async () =>{
  try {
    const res = await p(false)
  } catch (error) {
    console.log( error ); // "失败"
  }
}
fn()
异步异常
// 宏任务
try {
  setTimeout(function() {
   console.log(b);
  }, 0);
 } catch (error) {
  console.log(error); // 此处不执行
 }
 
// 微任务
try {
  new Promise(() => {
   throw new Error('new promise throw error');
  });
 } catch (error) {
  console.log(error); // 此处不执行
 }
只会抛出一层、不会向上冒泡
try {
  try {
    throw new Error('oops');
  }
  catch (ex) {
    console.log('inner'); // inner
  }
  finally {
    console.log('finally'); // finally
  }
}
catch (ex) {
  console.log('outer'); // 此处不执行
}

2、promise.catch()

const p = (rect) => {
  return new Promise((resolve, reject) => {
    if (rect) resolve("成功");
    else reject("失败");
  });
};

p(true)
  .then(
    (res) => {
      // 抛出错误
      return p(false);
    },
    (e) => {
      // 不执行
      return e;
    }
  )
  .then(
    (res) => {
      // 不执行
      return res;
    },
    (e) => {
      // 执行
      return e;
    }
  )
  .then(
    (res) => {
      // 执行
      console.log("then2", res);
      // return res;
      return p(false);
    },
    (e) => {
      // 不执行
      console.log("then2",e);
      return e;
    }
  )
  .catch((e) => {
    // 执行的条件
    // 1、抛出异常的函数内没使用 return 永远进不了 catch
    // 2、如果前面的 then 中处理过 error、则不再被 catch
    // 3、其它异常情况可进入 catch 
    console.log('catch', e);
    return e;
  })
  .finally((e) => {
    // 必执行、不接受任务参数
    console.log(e); // undefined
  });