山东做网站找谁网站建设指导方案

当前位置: 首页 > news >正文

山东做网站找谁,网站建设指导方案,六 网站建设方案.,seo收录查询工具异常处理方案 在JS开发中#xff0c;处理异常包括两步#xff1a;先抛出异常#xff0c;然后捕获异常。 为什么要做异常处理 异常处理非常重要#xff0c;至少有以下几个原因#xff1a; 防止程序报错甚至停止运行#xff1a;当代码执行过程中发生错误或异常时#x…异常处理方案 在JS开发中处理异常包括两步先抛出异常然后捕获异常。 为什么要做异常处理 异常处理非常重要至少有以下几个原因 防止程序报错甚至停止运行当代码执行过程中发生错误或异常时如果没有适当的异常处理机制程序可能会报错、停止运行甚至崩溃。通过处理异常我们可以捕获错误并采取适当的措施避免系统报错。 错误排查和调试异常处理有助于定位和排查错误。可以通过捕获异常并输出相关信息比如打印日志、错误上报、跟踪堆栈等等以便快速定位问题所在并进行调试和修复。 提高代码健壮性和可靠性可以采取适当的措施处理潜在的异常情况从而减少程序出错的可能性。 提升用户体验通过兜底、容错、容灾等异常处理方案可以向用户提供有效的错误信息提示而不是让用户界面无响应甚至白屏。
抛出异常 抛出异常的使用场景举例 我们经常会封装一些工具函数这些函数可能给自己用也可能给外部团队用。 在函数内部如果不符合预期的业务逻辑或者遇到异常情况时很多人的写法是直接 return不往下执行了。但是 return 的写法存在一个很大的弊端调用者不知道是因为函数内部没有正常执行还是执行的返回结果就是一个undefined。return 的写法只是规避了问题没有解决问题。建议的做法是我们需要手动抛出异常。 捕获异常 如果只是抛出异常而不捕获异常的话是比较危险的。这意味着当前任务立即终止不再执行当然后续的其他任务会正常执行。此外这个异常信息会层层往上抛给上层的调用者。如果一直未被捕获则最终会抛给浏览器浏览器控制台就会报错。 接下来我们看一下不同代码场景下的异常处理方案。 上报异常 如果有必要的话你可以把异常信息和日志上报给监控服务器然后集中分析。我每天上班第一件事就是打开监控系统看错误日志然后对症下药解决问题。 同步代码的异常处理 通过 throw 抛出异常 我们可以通过 throw关键字抛出一个用户自定义的异常。当代码执行时遇到 throw 语句时当前函数会停止停止即当前函数 throw 后面的代码不会再执行。 throw 意思是告诉调用者当前被调用的函数报错了调用者接下来需要捕获异常或者修改代码逻辑。 可以在 throw 的后面添加表达式或者数据类型将添加的内容抛出去。数据类型可以是number、string、boolean、对象等。 代码举例 function sum(num1, num2) {if (typeof num1 ! number) {throw type error: num1传入的类型有问题, 必须是number类型}​if (typeof num2 ! number) {throw type error: num2传入的类型有问题, 必须是number类型}​return num1 num2}​sum(a, b); 打印结果 当然我们还可以 throw一个封装好的对象。比如 class myError {constructor(errCode, errMsg) {this.errCode errMsg;this.errMsg errMsg;}}​function foo() {throw new myError(-1, not login);}​foo(); 上面这种写法比较麻烦一般不这么写。其实JS中已经内置了 Error 类专门用于生成错误信息。 Error 类 JS内置的 Error 类非常好用。 代码举例 function foo() {throw new Error(not login);}​​foo(); 打印结果 上面的打印结果可以看到通过 Error 抛出来的错误不仅可以看到报错信息还可以看到调用栈便于快速定位问题所在。非常方便。 通过 try catch 捕获异常 同步代码只抛出异常不捕获异常的代码举例 function foo() {throw new Error(not login);}​foo();// 当前任务立即终止不再执行下面这行代码和 foo() 都在同一个 同步任务 中console.log(qianguyihao); 打印结果 可以看到最后一行的 log 并没有执行。 我们可以使用 try catch 抛出异常 对上述代码进行改进。代码举例 function foo() {throw new Error(not login);}​// 通过 try catch 手动捕获异常try {foo();} catch (err) {console.log(err);}​// 当前任务的后续代码会继续执行console.log(qianguyihao); 打印结果 通过 try catch finally 捕获异常 如果有些代码必须要执行我们可以放到 finally 里。 不管是否遇到异常finally的代码一定会执行。 如果 try 和 finally 中都有返回值那么会使用finally中的返回值。
代码举例 function foo() {throw new Error(not login);}​// 通过 try catch 捕获异常try {foo();} catch (err) {console.log(err);} finally {console.log(finally)}​// 后续代码会继续执行console.log(qianguyihao); try catch 只能捕获同步代码的异常 try catch只能捕获同步代码里的异常而 Promise.reject() 是异步代码。 原因是当异步函数抛出异常时对于宏任务而言执行函数时已经将该函数推入栈此时并不在 try-catch 所在的栈所以 try-catch 并不能捕获到错误。对于微任务而言比如 promisepromise 的构造函数的异常只能被自带的 reject 也就是.catch 函数捕获到。 参考链接 try-catch 能抛出 promise 的异常吗 使用 window.onerror 监听未被捕获的代码异常 如果JS代码抛出了异常但没有进行捕获我们可以使用 JS 自带的 window.onerror 事件监听到这些错误。 代码举例 // 监听同步代码的异常window.onerror (event) {console.error(onerror 监听到未被捕获的异常:, event)};​function foo1() {throw new Error(not login);}​function foo2() {throw new Error(network error);}​foo1();foo2(); 打印结果 Promise 的异常处理 reject() 会自动抛出异常 在使用 Promise 时当我们调用了 reject() 之后系统会自动抛出异常不需要我们手动抛出异常。这是 Promise的内部机制。但是我们需要手动捕获异常。 当 Promise 进入 rejected状态之后会触发 catch()方法的执行捕获异常。此时成功完成了Promise异常处理的闭环。 在then() 中抛出异常重要 当then()方法传入的回调函数中如果遇到异常或者手动抛出异常那么then()所返回的新的 Promise 会进入rejected 状态进而触发新Promise 的 catch() 方法的执行做异常捕获。 场景1在then()方法传入的回调函数中如果代码在执行时遇到异常系统会自动抛出异常。此时我们需要在 catch() 里手动捕获异常否则会报错。 自动抛出异常的代码举例由于没有捕获异常所以会报错 const myPromise new Promise((resolve, reject) {resolve(qianguyihao1 fulfilled);});​myPromise.then(res {console.log(res1:, res);// 显然person 并没有 forEach()方法。所以代码在执行时会遇到异常。const person { name: vae };person.forEach(item {console.log(item:, item);})// 这行代码不会执行因为上面的代码报错了console.log(qianguyihao2);}).then(res {console.log(res2:, res);})​// 定时器里的代码正常执行setTimeout(() {console.log(qianguyihao3);}, 100) 运行结果 代码改进代码在执行时遇到异常此时我们捕获异常所以系统不会报错这才是推荐的写法 const myPromise new Promise((resolve, reject) {resolve(qianguyihao1 fulfilled); });myPromise.then(res {console.log(res1:, res);// 显然person 并没有 forEach()方法。所以代码在执行时会遇到异常。const person { name: vae };person.forEach(item {console.log(item:, item);})// 这行代码不会执行因为上面的代码报错了console.log(qianguyihao2); }).then(res {console.log(res2:, res); }).catch(err {// 在 catch()方法传入的会调函数里捕获异常console.log(err2:, err); })// 定时器里的代码正常执行 setTimeout(() {console.log(qianguyihao3); }, 100) 打印结果 场景2在then()方法传入的回调函数中如果我们手动抛出异常此时我们需要在 catch() 里手动捕获异常否则会报错。 代码举例手动抛出异常未捕获所以会报错 const myPromise new Promise((resolve, reject) {resolve(qianguyihao fulfilled 1); });myPromise.then(res {console.log(res1:, res);// 手动抛出异常throw new Error(qianguyihao rejected 2) }).then(res {console.log(res2:, res); })// 定时器里的代码正常执行 setTimeout(() {console.log(qianguyihao3); }, 100) 打印结果 代码改进代码在执行时遇到异常此时我们捕获异常所以系统不会报错这才是推荐的写法 const myPromise new Promise((resolve, reject) {resolve(qianguyihao fulfilled 1); });myPromise.then(res {console.log(res1:, res);// 手动抛出异常throw new Error(qianguyihao rejected 2) }).then(res {console.log(res2:, res); }, (err) {console.log(err2:, err); })// 定时器里的代码正常执行 setTimeout(() {console.log(qianguyihao3); }, 100) 打印结果 使用 unhandledrejection 事件监听未被捕获的Promise异常 如果Promise抛出了异常但没有进行捕获我们可以使用JS自带的 unhandledrejection 事件监听到这些错误。这个事件非常有用尤其是当我们需要集中做日志收集时屡试不爽。这个事件只能用于监听 Promise 中的异常不能用于其他同步代码的异常。 先来看下面这行代码 const myPromise new Promise((resolve, reject) {console.log(qianguyihao1);reject(not login);console.log(qianguyihao2); }) 打印结果 上面的代码抛出了异常但没有捕获异常所以我们可以用 unhandledrejection 事件监听到。代码举例 // 监听未被捕获的 Promise 异常 window.addEventListener(unhandledrejection, (event) {console.error(unhandledrejection 监听到异常写法1: \({event.reason}) });window.onunhandledrejection event {console.error(unhandledrejection 监听到异常写法2: \){event.reason}); };window.onerror (event) {console.error(onerror 监听到异常:, event); };const promise1 new Promise((resolve, reject) {reject(not login); })const promise2 new Promise((resolve, reject) {throw new Error(network error);resolve(); }) 打印结果 可以看到promise1 和 Promise2 的异常都被 unhandledrejection 事件收集到了。 代码举例2 window.addEventListener(unhandledrejection, (event) {console.error(unhandledrejection 监听到异常: ${event.reason}) });window.onerror (event) {console.error(onerror 监听到异常:, event); };const myPromise new Promise((resolve, reject) {setTimeout(() {throw new Error(not login);resolve();}, 100); }) 打印结果 上面的代码中unhandledrejection 无法监听异常因为定时器里的代码属于宏任务。 resolve()之后再报错无效 代码举例 const myPromise new Promise((resolve, reject) {resolve(fulfilled);throw new Error(自定义错误); });myPromise.then(res {console.log(res, res);return res 1; }).catch(err {console.log(err, err); }); 打印结果 res fulfilled 上方代码中第3行的异常代码相当于没写。因为 resolve()之后Promise的状态会立即进入 fulfilled然后走到 then()状态不可逆。 async await 的异常处理 捕获异常 代码举例 function requestData1() {return new Promise((resolve, reject) {reject(任务1失败);}) }function requestData2() {return new Promise((resolve, reject) {resolve(任务2成功);}) }async function getData() {// requestData1 在执行时遇到异常await requestData1();/由于上面的代码在执行是遇到异常所以这里虽然什么都没写底层默认写了如下代码return Promise.reject(任务1失败);/// 下面这两行代码不会再执行了因为上面的代码遇到了异常console.log(qianguyihao1);await requestData2(); }getData();// 【注意】定时器里的代码会正常实行因为它在另外一个宏任务里不在上面的微任务里 setTimeout(() {console.log(qianguyihao2); }, 100) 打印结果 所以为了避免上述问题我们还需要手动捕获异常。我们捕获到异常之后这个异常就不会继续网上抛了更不会抛给浏览器。 高级用法 ###