js
uniapp跨平台性
通过条件编译,各平台特有api调用。
手写节流和防抖
1.函数节流:规定在一个单位时间内,只能触发一次函数,在函数执行一次之后,该函数在指定的时间期限内不再工作
function throttle(fn,delay){
let valid = true
return function() {
if(!valid){
//暂停执行
return false
}
// 执行
valid = false
setTimeout(() => {
fn()
valid = true;
}, delay)
}
}
2.函数防抖:在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时;。效果:如果短时间内大量触发同一事件,只会执行最后一次函数。
function debounce(fn,delay){
let timer = null
return function() {
if(timer){
clearTimeout(timer) //再次计时
timer = setTimeout(fn,delay)
}else{
timer = setTimeout(fn,delay) // 开始计时
}
}
}
概念:Event Loop
JS引擎常驻于内存中,等待宿主将JS代码或函数传递给它。
也就是等待宿主环境分配宏观任务,反复等待 - 执行即为事件循环。
Event Loop中,每一次循环称为tick,每一次tick的任务如下:
- 执行栈选择最先进入队列的宏任务(一般都是script),执行其同步代码直至结束;
- 检查是否存在微任务,有则会执行至微任务队列为空;!!!
- 如果宿主为浏览器,可能会渲染页面;
- 开始下一轮tick,执行宏任务中的异步代码(setTimeout等回调)
概念:宏任务和微任务
ES6 规范中,microtask 称为
jobs
,macrotask 称为task
宏任务是由宿主发起的,而微任务由JavaScript自身发起。在ES3以及以前的版本中,JavaScript本身没有发起异步请求的能力,也就没有微任务的存在。在ES5之后,JavaScript引入了
Promise
,这样,不需要浏览器,JavaScript引擎自身也能够发起异步任务了。
宏任务(macrotask) | 微任务(microtask) | |
---|---|---|
发起对象 | 宿主(Node、浏览器) | JS引擎 |
运行顺序 | 后运行 | 先运行 |
发起的事件 | 1. script (可以理解为外层同步代码) 2. setTimeout/setInterval 3. UI rendering/UI事件 4. postMessage,MessageChannel 5. setImmediate,I/O(Node.js) | 1. Promise 2. MutaionObserver 3. Proxy 4. process.nextTick(Node.js) |
会不会触发新一轮Tick | 会 | 不会 |
js为什么要设计成单线程
js是作为浏览器的脚本语言,主要是实现用户与浏览器的交互,以及操作dom;如果有一个线程要修改一个dom元素,另一个线程要删除这个dom元素,此时浏览器就会一脸茫然。