try...catch 是否能捕获异步异常
代码示例:
try {
setTimeout(() => {
throw new Error("err");
}, 200);
} catch (err) {
console.log(err);
}
try {
Promise.resolve().then(() => {
throw new Error("err");
});
} catch (err) {
console.log(err);
}
通过上述代码:
才知道 try...catch 不能异步捕获代码错误。在 JavaScript 中,setTimeout 是一个异步函数,它的回调函数会在指定的延时后被放入事件队列,等待当前执行栈清空后才执行。因此,当 setTimeout 的回调函数执行并抛出错误时,try...catch 已经执行完毕,无法捕捉到异步回调中的错误。 正确的做法是在异步操作中直接处理错误,例如使用回调函数、Promises 或者 async/await 结合 try...catch
new Promise((resolve, reject) => {
setTimeout(() => {
try {
throw new Error("err");
} catch (err) {
reject(err);
}
}, 200);
})
.then(() => {
// 正常执行时的处理逻辑
})
.catch((err) => {
console.log(err); // 这里会捕捉到错误
});
在 Promise 中抛出一个错误(例如通过 throw 语句)会导致 Promise 被拒绝(或失败)。要正确处理这个错误,需要在 Promise 链中使用.catch 方法或者在一个 async 函数中使用 try...catch。
// 方法一
Promise.resolve()
.then(() => {
throw new Error("err");
})
.catch((err) => {
console.log(err); // 这里会捕捉到错误
});
// 方法二
async function handleError() {
try {
await Promise.resolve().then(() => {
throw new Error("err");
});
} catch (err) {
console.log(err); // 这里会捕捉到错误
}
}
handleError();
http 缓存中 no-cache 与 no-store 的区别是什么
在 HTTP 缓存中,no-cache
和no-store
是两种不同的缓存指令,它们的区别如下:
一、no-cache
-
含义:
-
当设置了
no-cache
指令时,这并不意味着不使用缓存。相反,它表示在使用缓存之前,必须先与服务器进行验证,以确定缓存的资源是否仍然有效。 -
这意味着浏览器在使用缓存的资源之前,会向服务器发送一个条件请求(通常是使用
If-Modified-Since
或If-None-Match
头部),询问服务器该资源是否有更新。如果服务器返回 304 Not Modified 状态码,表示资源没有更新,浏览器可以使用缓存的资源;如果服务器返回新的资源内容,表示资源有更新,浏览器需要使用新的资源。
-
二、no-store
-
含义:
no-store
指令表示绝对不允许缓存资源。这意味着浏览器在接收到带有no-store
指令的响应后,不会将资源存储在任何缓存中,包括浏览器缓存、代理服务器缓存等。每次请求都必须从服务器获取最新的资源。
总之,no-cache
表示在使用缓存之前需要与服务器进行验证,而no-store
表示绝对不允许缓存资源。根据不同的需求,可以选择合适的缓存指令来控制资源的缓存行为。
http 缓存 header 中的 Date 与 Last-Modified 有什么不同
一、含义不同
-
Date
:表示消息产生的时间。服务器用这个时间来标记响应报文的生成时间,它反映了服务器生成响应的时刻。例如,“Mon, 07 Oct 2024 12:34:56 GMT”,这个时间是服务器根据其自身的时钟生成的。 -
Last-Modified
:指示资源的最后修改时间。它表示服务器上该资源最后被修改的时间。比如,一个网页文件最后一次被编辑的时间就可以通过这个字段告知客户端。例如,“Mon, 01 Sep 2024 10:20:30 GMT”。
二、用途不同
-
Date
:- 客户端可以根据这个时间来判断响应的新鲜度。例如,如果客户端本地有缓存,它可以通过比较缓存的时间和响应中的
Date
来确定是否需要使用缓存。 - 用于计算响应的年龄等缓存相关的参数。
- 客户端可以根据这个时间来判断响应的新鲜度。例如,如果客户端本地有缓存,它可以通过比较缓存的时间和响应中的
-
Last-Modified
:- 主要用于缓存控制。客户端在后续的请求中可以通过
If-Modified-Since
请求头将这个时间发送给服务器,询问服务器资源是否在这个时间之后被修改过。如果没有被修改,服务器可以返回一个状态码为 304(Not Modified)的响应,告知客户端可以使用缓存中的资源,从而减少传输的数据量和提高响应速度。 - 有助于客户端判断资源是否已经过期,以便决定是否需要重新获取资源。
- 主要用于缓存控制。客户端在后续的请求中可以通过
综上所述,Date
主要表示响应的生成时间,而Last-Modified
表示资源的最后修改时间,它们在 HTTP 通信中起着不同的作用,共同为缓存控制和资源管理提供重要信息。
对于已经 import 但未实际使用的模块使用 webpack 还会对它打包吗
在使用 Webpack 进行打包时,对于已经导入(import)但未实际使用的模块,通常情况下不会被打包进去,但这也取决于具体的配置和使用场景。
一、默认行为
在默认情况下,Webpack 会进行“树摇”(tree shaking)操作。树摇是一种优化技术,它可以检测和移除未被使用的代码。如果一个模块被导入但在代码中没有被实际使用,Webpack 会尝试识别并排除这个模块,以减小最终打包文件的大小。
如何进行代码质量检测
一、静态代码分析
-
使用静态代码分析工具
- 例如 SonarQube、Checkstyle、PMD 等。这些工具可以检查代码中的潜在问题,如代码风格不符合规范、未使用的变量、复杂度过高的方法等。
- SonarQube 可以对多种编程语言进行分析,提供全面的代码质量报告,包括代码重复率、代码复杂度、潜在的漏洞等。
- Checkstyle 主要用于检查 Java 代码是否符合编码规范,如缩进、命名规范、注释等。
- PMD 可以检测 Java 代码中的各种问题,如空指针引用、资源未释放等。
-
遵循编码规范
- 制定统一的编码规范,包括命名规范、缩进风格、注释规范等。确保团队成员都遵循这些规范,以提高代码的可读性和可维护性。
- 例如,在 Java 中,变量名通常采用驼峰命名法,方法名采用动词+名词的形式。
二、单元测试
-
编写单元测试用例
- 针对代码中的每个函数、方法或类编写单元测试用例,确保代码的正确性。单元测试应该覆盖各种输入情况,包括正常情况和边界情况。
- 例如,对于一个加法函数,可以编写测试用例来测试两个正数相加、一个正数和一个负数相加、两个负数相加等情况。
-
使用测试框架
- 如 JUnit(Java)、pytest(Python)等。这些测试框架提供了方便的断言方法和测试运行环境,使单元测试的编写和执行更加容易。
- JUnit 提供了注解和断言方法,方便编写和组织单元测试。可以使用@Test 注解标记测试方法,使用断言方法如 assertEquals、assertTrue 等来验证测试结果。
三、代码审查
-
团队成员之间进行代码审查
- 定期进行代码审查,让其他团队成员对代码进行审查。这可以发现代码中的潜在问题、提高代码质量,并促进团队成员之间的知识共享。
- 在代码审查中,可以关注代码的可读性、可维护性、性能、安全性等方面。
-
自动化代码审查工具
- 如 Gerrit、Phabricator 等。这些工具可以帮助管理代码审查流程,记录审查意见和修改历史,确保代码审查的有效性和可追溯性。
- Gerrit 可以与版本控制系统集成,提供代码审查、合并请求管理等功能。审查者可以在网页上对代码进行审查,提出意见和建议,开发者可以根据审查意见进行修改。
四、持续集成和持续部署(CI/CD)
-
建立 CI/CD 流程
- 使用工具如 Jenkins、GitLab CI/CD 等建立持续集成和持续部署流程。每次代码提交后,自动触发构建、测试和部署流程,确保代码的质量和稳定性。
- 在 CI/CD 流程中,可以集成静态代码分析、单元测试、代码审查等环节,及时发现和修复代码中的问题。
-
监控和反馈
- 建立监控系统,实时监测应用的性能和可用性。如果出现问题,及时反馈给开发团队,以便进行修复。
- 可以使用监控工具如 Prometheus、Grafana 等,设置报警规则,当指标超过阈值时及时通知开发团队。
五、性能测试
-
进行性能测试
- 使用性能测试工具如 JMeter、LoadRunner 等对应用进行性能测试。模拟多用户并发访问,测试应用的响应时间、吞吐量、资源利用率等指标。
- 根据性能测试结果,优化代码的性能,如优化数据库查询、减少网络请求、提高算法效率等。
-
压力测试
-
进行压力测试,模拟高负载情况下应用的表现。这可以帮助发现应用在极端情况下的性能问题和潜在的瓶颈。
-
压力测试可以逐渐增加负载,观察应用的性能变化,直到达到系统的极限。
-