说明:可直接cv代码到控制台 F12 运行
一、Promise.all 多接口请求,所有请求完成后打印所有请求结果
// 定义接口路径
const url = [100, 200, 300, 400, 500, 600, 700, 800, 900, 2000]
// 模拟请求
function request(u) {
return new Promise(resolve => {
setTimeout(() => {
if (u === 500 || u === 700) {
// 模拟请求报错时,防止 Promise.all 执行中断
// 使用 resolve 而不使用 reject
resolve('error')
} else {
// 成功时
resolve(u)
}
}, u)
})
// return axios.get(url)
}
// Promise.all 等待所有都完成
async function allRequest(urls) {
const res = await Promise.all(urls.map(u => {
return request(u)
}))
const newRes = res.filter(r => r !== 'error')
// Promise.all 等待请求全部完成才输出结果
console.log(res)
console.log(newRes)
}
// 调用
allRequest(url)
二、递归节点查找
// 模拟树
const treeData = [
{
name: "节点1",
children: [
{
name: "节点1-1",
children: [],
},
{
name: "节点1-2",
children: [
{
name: "节点1-2-1",
children: [],
},
],
},
],
},
{
name: "节点2",
children: [
{
name: "节点2-1",
children: [],
},
],
},
];
/**
*方法一:
*/
// 递归
function fn(arr, name, callback) {
arr.forEach(v => {
if (v.name === name) callback(v)
if (v.children) fn(v.children, name, callback)
})
}
// 执行函数
fn(treeData, '节点1-2-1', res => {
console.log(res)
})
/**
*方法二:
*/
function getTreeName(list, name) {
let res = null
for (let i = 0; i < list.length; i++) {
let item = list[i]
item.name === name ? res = item.name : ''
if (res) break
if (item.children.length) res = getTreeName(item.children, name)
}
return res
}
const treeName = getTreeName(treeData, '节点2')
console.log(treeName)
三、渲染性能代码优化
1、代码优化
// 初始化 dom
const demo = document.createElement('div')
demo.setAttribute('id', 'demo')
document.body.append(demo)
// 原代码
const el = document.querySelector('#demo');
for (let i = 0; i < 1000; i++) {
el .innerHTML += `<option value="${i}">第${i}个选项</option>`;
}
// 优化后
const el = document.querySelector('#demo');
let htmls = ''
for (let i = 0; i < 1000; i++) {
htmls += `<option value="${i}">第${i}个选项</option>`;
}
el.innerHTML = htmls
2、再次优化,防抖?懒加载??
// 初始化 dom
const demo = document.createElement('div')
demo.setAttribute('id', 'demo')
document.body.append(demo)
// 定义变量
let htmls = ''
let oldEl = ''
const el = document.querySelector('#demo');
// 防抖(只是在最后一次事件结束后才触发一次函数)
function fd(callback, delay) {
let time = null
return () => {
clearTimeout(time)
time = setTimeout(callback, delay)
}
}
// 懒加载
function lazy(callback, oldEl, noDataLength = 150) {
if (oldEl.length >= noDataLength) {
if (!document.getElementById('no-data')) {
const div = document.createElement('div')
div.setAttribute('id', 'no-data')
div.innerText = '没有更多数据了...'
el.appendChild(div)
}
return false
}
const st = document.documentElement.scrollTop // 滚动条滚动距离
const cH = document.documentElement.clientHeight // 可视区高度
const sH = document.body.scrollHeight // 浏览器所有内容高度
if (st + cH > sH) callback()
}
// 初始化模拟数据
window.addEventListener('load', () => {
for (let i = 0; i < 50; i++) {
htmls += `<option value="${i}">第${i}个选项</option>`;
}
el.innerHTML = htmls
})
// 使用防抖 + 懒加载
window.addEventListener('scroll', fd(() => {
lazy(() => {
oldEl = document.querySelectorAll('#demo option');
for (let i = 0; i < 50; i++) {
let option = document.createElement('option')
option.setAttribute('value', oldEl.length + i)
option.innerText = `第${oldEl.length + i}个选项`
el.appendChild(option)
}
}, oldEl, 100)
}, 500))