180期题目
1. vue中data为啥是一个函数?而new vue实例中又是个对象
2. es6新特性有哪些
3.for循环和map循环有什么区别
上面问题的答案会在第二天的公众号(程序员每日三问)推文中公布
也可以小程序刷题,已收录500+面试题及答案
179期问题及答案
1. JS是单线程的,为啥JS有异步任务?
JS 是一门单线程的语言,这意味着它一次只能执行一个任务。然而,JS 中引入了异步任务的概念,这是为了解决在执行耗时任务时不阻塞其他代码执行的问题。让我详细解释一下为什么 JS 中有异步任务。
1. 阻塞与非阻塞
在同步编程中,代码按顺序执行,如果有一个耗时的任务,整个程序会被阻塞,直到这个任务完成。这会导致用户体验下降,特别是在前端浏览器环境中。
异步编程的目的是允许程序在执行长时间运行的任务时,能够继续执行其他任务而不阻塞。这种方式称为非阻塞。
2. 事件循环
在 JS 中,异步任务的实现依赖于事件循环机制。JS 运行时环境维护一个主线程,该线程负责执行代码和处理事件。事件循环会不断地检查消息队列,如果有消息(即异步任务完成),则会将消息添加到调用栈中执行。
3. 异步任务的例子
a. 定时器
console.log('Start');
setTimeout(() => {
console.log('Timeout callback');
}, 1000);
console.log('End');
在这个例子中,setTimeout
是一个异步任务,它会在指定的时间后将回调函数放入消息队列。在这个过程中,主线程可以继续执行其他任务。
b. AJAX 请求
console.log('Start');
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log(data));
console.log('End');
在这个例子中,fetch
发起了一个异步的网络请求,它不会阻塞主线程的执行,而是在请求完成后将回调函数添加到消息队列。
4. 回调函数与 Promise
最初,异步任务主要通过回调函数来实现,但这容易导致回调地狱(callback hell)。为了更好地处理异步操作,ES6 引入了 Promise。
console.log('Start');
const fetchData = () => {
return new Promise((resolve, reject) => {
// 异步操作
setTimeout(() => {
resolve('Data fetched successfully');
}, 1000);
});
};
fetchData()
.then(data => console.log(data))
.catch(error => console.error(error));
console.log('End');
Promise 提供了更清晰的异步流程控制,避免了回调地狱,同时使错误处理更为灵活。
总结
虽然 JS 是单线程的,但通过引入异步任务,它能够在执行耗时任务时不阻塞其他代码的执行,从而提高程序的性能和用户体验。异步任务通过事件循环和回调函数的方式实现,而现代 JS 还引入了 Promise 和 async/await
等机制,使异步编程更加便利和可读。
2. vue-router有哪几种路由卫士?
Vue Router 提供了多种路由卫士(Route Guards)来允许开发者在导航过程中执行代码。这些路由卫士可以帮助你控制导航的行为。以下是 Vue Router 中常用的路由卫士:
全局前置守卫 (beforeEach):
使用方式:
router.beforeEach((to, from, next) => {})
在路由切换开始时调用,常用于进行全局的身份验证、权限控制等。
全局解析守卫 (beforeResolve):
使用方式:
router.beforeResolve((to, from, next) => {})
在导航被确认之前调用,用于异步路由组件解析完成之后执行一些操作。
全局后置守卫 (afterEach):
使用方式:
router.afterEach((to, from) => {})
在导航完成之后调用,常用于记录页面浏览历史、埋点统计等。
路由独享守卫 (beforeEnter):
使用方式:在路由配置中直接添加
beforeEnter
属性仅对单个路由生效,用于在进入某个路由前执行一些特定的逻辑。
组件内的守卫:
beforeRouteEnter
: 在路由进入的时候调用,此时组件还未创建。beforeRouteUpdate
: 在路由更新时调用,可以在当前路由被复用的时候调用。beforeRouteLeave
: 在离开路由时调用,常用于在用户关闭页面或者切换到其他页面前执行一些逻辑。
这些路由卫士可以组合使用,以满足不同场景下的需求。使用路由卫士可以对导航过程中的不同阶段进行控制和定制,从而更好地管理路由。在实际项目中,合理利用这些卫士可以增强应用的稳定性和用户体验。
3. http缓存有哪些?
HTTP 缓存是一种通过在客户端和服务器之间存储资源的副本,以减少数据传输和提高性能的机制。HTTP 协议定义了多种缓存机制,以下是常见的 HTTP 缓存策略:
强缓存(Freshness):
Expires 头: 服务器返回资源时,在响应头中设置一个过期时间,浏览器会在过期时间前使用缓存。例如:
Expires: Wed, 21 Oct 2022 07:28:00 GMT
Cache-Control 头: 提供更灵活的缓存机制,可以设置相对时间、绝对时间或者禁止缓存等,优先级高于
Expires
。Cache-Control: max-age=3600 // 缓存时间为 3600 秒
协商缓存(Validation):
Last-Modified 和 If-Modified-Since 头: 当客户端首次请求资源时,服务器会返回资源的最后修改时间(
Last-Modified
),客户端再次请求时,通过If-Modified-Since
头将该时间发送给服务器,服务器根据时间判断资源是否有更新。Last-Modified: Mon, 18 Jan 2022 12:00:00 GMT
ETag 和 If-None-Match 头: 类似于
Last-Modified
,但是使用一个唯一的标识符(ETag
)代替最后修改时间,如果资源有更新,服务器返回新的ETag
,客户端再次请求时通过If-None-Match
判断。ETag: "abcd1234"
Cache-Control 扩展:
no-store: 禁止缓存,每次请求都要向服务器重新获取资源。
Cache-Control: no-store
no-cache: 强制确认缓存,客户端每次请求都要向服务器验证资源是否过期。
Cache-Control: no-cache
must-revalidate: 在过期之后,强制向服务器进行验证,如果无法验证则不能使用缓存。
Cache-Control: must-revalidate
这些缓存策略可以单独使用或者结合使用,根据具体的场景和需求选择合适的策略,以优化资源加载和提高应用性能。在开发中,合理利用 HTTP 缓存可以减少不必要的网络请求,提升用户体验。
因为微信公众号修改规则,如果不标星或点在看,你可能会收不到我公众号文章的推送,原创不易,请大家将本公众号星标,看完文章后记得点下赞或者在看,谢谢各位!
学习不打烊,充电加油只为遇到更好的自己,每天早上9点纯手工发布面试题,每天坚持花20分钟来学习与思考,在千变万化,类库层出不穷的今天,不要等到找工作时才狂刷题,提倡每日学习。