语句类型
比较常见的语句包括变量声明、表达式、条件、循环等,下面是大体分类。
:::
1.为何try里面放return,finally还会执行,理解其内部机制
印象笔记/js基础
https://www.jianshu.com/p/580a88a9493b
2.JavaScript如何实现异步编程,可以详细描述EventLoop机制
印象笔记react基础/event-loop
事件轮回开始进行,宏任务第一次开始执行,就会把整个js代码块放入调用栈执行,他是后进先出的执行机制 ,也就是把整个代码块从上向下执行。会依次判断代码是同步还是异步,同步代码立即执行。而异步代码会放到Event Table中,通过web Api判断是宏任务还是微任务。然后将其放入对应的事件队列 。宏任务每执行完一次,都要询问微任务队列是否有任务, 有任务就依次放入调用栈执行,清空微任务队列,然后再执行宏任务,就这样循环往复的询问宏任务队列和微任务队列。
3.宏任务和微任务分别有哪些
宏任务:
# | 浏览器 | node |
---|---|---|
I/O | ✅ | ✅ |
setTimeout (延时器) | ✅ | ✅ |
setInterval(计时器) | ✅ | ✅ |
setImmediate (下面详解) | ❌ | ✅ |
requestAnimationFrame | ✅ | ❌ |
script标签(同步代码)/ ui渲染 | ✅ | ❌ |
微任务:
# | 浏览器 | node |
---|---|---|
process.nextTick | ❌ | ✅ |
MutationObserver | ✅ | ❌ |
Promise.then catch finally | ✅ | ✅ |
async await | ✅ | ✅ |
什么是requestAnimationFrame
什么是MutationObserver
创建并返回一个新的 MutationObserver 它会在指定的DOM发生变化时被调用
什么是setImmediate
什么是process.nextTick
setImmediate
该方法用来把一些需要长时间运行的操作放在一个回调函数里,在浏览器完成后面的其他语句后,就立刻执行这个回调函数
var immediateID = setImmediate(func, [param1, param2, ...]);
var immediateID = setImmediate(func);
immediateID 是这次setImmediate方法设置的唯一ID,可以作为 window.clearImmediate 的参数.
func 是将要执行的回调函数
参数param1 param2 ..都会直接传给函数func
window.clearImmediate 方法可以用来取消通过setImmediate设置的将要执行的语句, 就像 window.clearTimeout 对应于 window.setTimeout一样.
该方法可以用来替代 setTimeout(0) 方法来滞后完成一些需要占用大量cpu时间的操作.下面的JavaScript可以用来兼容那些不支持setImmediate方法的浏览器:
if (!window.setImmediate) {
window.setImmediate = function(func, args){
return window.setTimeout(func, 0, args);
};
window.clearImmediate = window.clearTimeout;
}
链接:https://www.jianshu.com/p/d207df1ca19e
4.可以快速分析一个复杂的异步嵌套逻辑,并掌握分析方法
5.使用Promise实现串行
// promise
const delay = (time) => {
return new Promise((resolve, reject) => {
console.log('wait',time);
setTimeout(() => {
console.log('exe');
resolve()
}, time *1000)
})
}
const arr = [1, 2, 3, 4,5];
// 1.reduce
arr.reduce((prev, next) => {
return prev.then(() => delay(next))
},Promise.resolve())
// 2.async + 循环 + await
(async () => {
for (let item of arr) {
await delay(item)
}
})()
// 3.普通循环,注意var声明提前问题
const p = Promise.resolve();
for (const i of arr) {
p = p.then(() => delay(i))
}
// 4.递归
const loop = (i, p = Promise.resolve()) => {
if(!arr[i]) return Promise.resolve()
return p.then(() => loop(i + 1, delay(arr[i])) )
}
loop(0)
// 5.for + await + of
// 通过查阅了for await of的规则,其实for await of和for of规则类似,只需要实现一个内部[Symbol.asyncIterator]方法即可
function createAsyncIterable(arr) {
return {
// Symbol.asyncIterator 符号指定了一个对象的默认异步迭代器。如果一个对象设置了这个属性,它就是异步可迭代对象,可用于for await...of循环。
[Symbol.asyncIterator]() {
return {
i: 0,
next() {
if(this.i < arr.length) {
return delay(arr[this.i]).then(() => ({
value: this.i,
done: false,
}))
}
return Promise.resolve({ done: true })
},
}
},
}
}
(async () => {
for await (i of createAsyncIterable(arr)) { }
})()
// 6.generator
function* gen() {
for (const i of arr) {
yield delay(i)
}
}
function run(gen) {
const g = gen();
const next = (data) => {
const result = g.next(data);
if (result.done) return result.value;
result.value.then((data) => next(data))
}
next()
}
run(gen)
https://blog.csdn.net/qq_45803050/article/details/123165188
https://juejin.cn/post/6844903801296519182
6.Node与浏览器EventLoop的差异
由于js是单线程语言,为了解决异步操作所以设计了事件循环
- 宏任务:setImmediate,setTimeout、setInterval 、script(整体 代码)、 I/O 操作、UI 渲染等
- 微任务:process.nextTick()、 new Promise().then(回调)、async和await、MutationObserver( html5新特性)
在事件循环中,宏任务和微任务分成了两类的队列,为了便于理解,微任务相当于是追加在宏任务队列后的一个独立的队列。
差异:setTimeout、setInterval
浏览器:
宏任务单个执行:每执行一个后,就会去执行掉微任务队列中的所有任务。
UI渲染:每次一个循环结束后(一个宏+整列微任务),如果需要会执行UI渲染。
实时添加:微任务执行过程中可以向本队列继续添加微任务并顺序执行。
Node:
队列执行:任务执行时,会执行队列中的所有任务(包括宏任务队列)
nextTick优先:微任务分的更细,node将nextTick回调单独化为一组微任务,所有nextTick队列可以和微任务队列一样实时添加,而且整个队列始终先于微任务队列执行。
执行阶段更多:
timers :setTimeout、setInterval
I/O callbacks :此回调中,setImmediate始终先于timers执行,因为,此阶段(2)执行完毕后,顺序就是5check了。
idle, prepare
poll
check : setImmediate
close callbacks
NodeJS 事件环和浏览器事件环的区别
任务队列个数不同
浏览器事件环有 2 个事件队列(宏任务队列和微任务队列)
NodeJS 事件环有 6 个事件队列
微任务队列不同
浏览器事件环中有专门存储微任务的队列
NodeJS 事件环中没有专门存储微任务的队列
微任务执行时机不同
浏览器事件环中每执行完一个宏任务都会去清空微任务队列
NodeJS 事件环中只有同步代码执行完毕和其它队列之间切换的时候会去清空微任务队列
微任务优先级不同
浏览器事件环中如果多个微任务同时满足执行条件,采用先进先出
NodeJS 事件环中如果多个微任务同时满足执行条件,会按照优先级执行
原文链接:https://blog.csdn.net/z591102/article/details/107151264/
https://www.likecs.com/show-306581837.html
https://www.jianshu.com/p/1122b93e42ce
7.如何在保证页面运行流畅的情况下处理海量数据
https://www.likecs.com/show-203720966.html
「前端进阶」高性能渲染十万条数据(时间分片) (详细)
可以用requestAnimationFrame 方法进行分片处理,requestAnimationFrame的步伐跟着系统的刷新步伐走。它能保证回调函数在屏幕每一次的刷新间隔中只被执行一次,这样就不会引起丢帧现象。