1. js限制并发请求
核心:
- 用缓冲队列存储请求
- 记录当前正在执行的请求数量
- run函数【判断个数是否在最大并发数内, 是则发请求并在结束回调内更改计数,并递归调起下一个请求】
class BufferControl {
bufferList = []; //缓冲队列
maxLen = 1; //当前允许执行的最大并发数量
currentQueenCount = 0; //当前正在执行的任务数量
add(fn) {
this.bufferList.push(fn);
this.run();
}
run() {
if (!this.bufferList.length) {
return;
}
while (this.bufferList.length && this.currentQueenCount < this.maxLen) {
let fn = this.bufferList.shift();
this.currentQueenCount++;
fn().then(() => {
this.currentQueenCount--;
this.run();
});
}
}
}
const reqs = new Array(10).fill(false).map((_, i) =>
() => new Promise(resolve => setTimeout(() => { console.log(i); resolve(i) }, 1000)))
const executeSerialMax = (reqs, max) => {
let curRequestCount = 0;
const run = function () {
if (!reqs.length) return;
while (reqs.length && curRequestCount < max) {
// console.log(new Date())
const task = reqs.shift();
curRequestCount++;
task().then().finally(_ => {
curRequestCount--;
run();
})
}
}
run();
}
executeSerialMax(reqs, 3)
2. 合法的URL
// 补全代码
// 开始符 ^
// 协议部分http(s):// 表示为((https|http|ftp|rtsp|mms)?:\/\/)
// 域名部分 表示为(([A-Za-z0-9]+-[A-Za-z0-9]+|[A-Za-z0-9]+)\.)+
// 顶级域名com cn等为2-6位 表示为([a-zA-Z]{2,6})
// 端口部分 表示为(:\d+)?, ?表示0次或1次
// 请求路径如/login 表示为 (\/.*)?
// 问号传参及哈希值如?age=1 表示为 (\?.*)?和(#.*)?
// 结束符 $
const _isUrl = url => {
return /^((http|https):\/\/)?(([A-Za-z0-9]+-[A-Za-z0-9]+|[A-Za-z0-9]+)\.)+([A-Za-z]+)(:\d+)?(\/.*)?(\?.*)?(#.*)?$/.test(url)
}
3. 获取地址栏中的参数
var str = "http://www.baidu.com?id=51028857&name=ceshi&age=8";
var reg = /([^?=&]+)=([^?=&]+)/g;
var result = {};
str.replace(reg, function ($1, $2, $3) {
result[$2] = $3;
});
console.log(result);
4. 数组去重
function repeatDel(arr) {
let set = new Set(arr);
return Array.from (set);
}
// console.log(repeatDel([1,1,2,2,3,4,5,4,3,3,2,1]));
function repeatDel_second(arr) {
let hasNum = {};
let newArr = [];
arr.forEach(item => {
!hasNum[item] ? ((hasNum[item] = true), (newArr.push(item))) : "";
});
return newArr;
}
// console.log(repeatDel_second([1,1,2,2,3,4,5,4,3,3,2,1]));
5. 扁平化
// 1. ...
// 二维变一维
Array.prototype.concat.apply([], [1,2,3,[4,5]]);
[].concat(...[1,2,3,[4,5]]);
// 多维
function flatten(arr) {
while(arr.some(item => Array.isArray(item))) {
arr = [].concat(...arr);
}
return arr;
}
// 2. 递归
function flatten1(arr) {
let result = [];
arr.map(item => {
if (Array.isArray(item)) {
result = result.concat(flatten1(item));
} else {
result.push(item);
}
})
return result;
}
// join split
// 注释
// var arr = [1,2,[3,[4,[5]]]];
// arr.join(",");
// "1,2,3,4,5"
// arr.toString()
// "1,2,3,4,5"
function flatten2(arr) {
return arr.join(",").split(",").map(item => parseInt(item));
}
// toString split
function flatten3(arr) {
return arr.toString().split(",").map(item => parseInt(item));
}
// reduce
function flatten4(arr) {
return arr.reduce((result, item) => {
return result.concat(Array.isArray(item) ? flatten4(item) : item);
}, [])
}
function flatten5(arr) {
// 扩展运算符实现扁平化
// while(arr.some(item => Array.isArray(item))) {
// arr = [].concat(...arr);
// }
// return arr;
// 递归
// let result = [];
// arr.map(item => {
// if(Array.isArray(item)) {
// result = result.concat(flatten5(item));
// } else {
// result.push(item);
// }
// })
// return result;
// reduce
// return arr.reduce((result, item) => {
// return result.concat(Array.isArray(item) ? flatten5(item) : item);
// }, []);
}
数组转树
const data =
[{ "id": 1, "parentId": null, "value": 1 }, { "id": 2, "parentId": 3, "value": 2 }, { "id": 3, "parentId": 1, "value": 3 }, { "id": 4, "parentId": 2, "value": 4 }];
function generateTree(data) {
let res = {};
const hash = {};
for (let i = 0; i < data.length; i++) {
hash[data[i].id] = { ...data[i] };
}
for (let i = 0; i < data.length; i++) {
let obj = data[i];
if (obj.parentId === null) {
res = hash[obj.id];
} else {
!hash[obj.parentId].children && (hash[obj.parentId].children = []);
// 注意push的是新拷贝的hash
hash[obj.parentId].children.push(hash[obj.id]);
}
}
return res;
}
console.log(generateTree(data))
防抖
短时间内连续触发的事件,重新触发事件就重新开始计时。
function debounce(fn, delay) {
let timer;
return function(args) {
const _this = this;
t
timer = setTimeout(() => {
fn.apply(_this, args)
}, delay)
}
}
节流
让某个时间期限内,事件处理函数只执行一次。
function throttle(fn, wait) {
let timeout;
return function(args) {
const _this = this;
if(!timeout) {
timeout = setTimeout(() => {
timeout = null;
fn.apply(_this, args);
}, wait);
}
}
}
持续更新中…