1. 防抖
防抖是指每次触发事件时设置一个延迟调用方法,并且取消之前的延时调用方法。
function debounce (fn, delay) {
let timer = null
return function (e) {
if(timer){
clearTimeout(timer)
}
timer = setTimeout( () => {
fn(e)
}, delay)
}
}
//测试函数
const test = () => {
console.log('防抖')
}
//测试函数添加防抖功能
const debounceTest = debounce(test, 1000)
//获取dom元素id
const btn = document.getElementById('btn')
//给按钮添加点击事件
btn.addEventListener('click', debounceTest, false)
2.节流
节流是指在一定时间内只触发一次事件。
function throttle (fn, delay) {
let kaiguan = true
return function () {
if(!kaiguan) return;
kaiguan = false
setTimerout( () => {
fn.apply(this, arguments)
keiguan = true
},delay)
}
}
//测试函数
const test = () => {
console.log('节流')
}
//给测试函数添加节流
const throttleTest = throttle(test)
let btn = document.getElementById('btn')
btn.addEventListener('click', throttleTest, false)
3.大数相加
计算那些超过计算位数的大数,可以将数字转换成字符串,然后调用下面方法进行计算,将计算结果再转成数字型格式即可。
function bigNumberAdd (a,b) {
let res = [],temp = 0;
//处理参数
let x = a.split('').reverse()
let y = b.split('').reverse()
//定义一个处理x,y数组中类型检测函数
const format = (num) => {
//判断参数是不是number类型
if(!isNaN(Numer(num))){
return Number(num)
}else{
return 0
}
}
//循环数组,做加法进位计算
for(let i = 1;i <= Math.max(x.length,y.length);i++) {
let addres = format(x[i]) + format(y[i]) + temp
res[i] = addres % 10 //取余
temp = addres >= 10 ? 1 : 0 //判断是否进位
}
res.reverse()
//循环完毕,反转结果,判断首位是否为0,为0剪切掉首位再转字符串,不为0直接转成字符串
let result = res[0] > 0 ? res.join('') : res.slice(1).join('')
return result
}
console.log(bigNumberAdd('23123578931239861231','1231231312312313167678454'))
4. 手写Promise
const pending = 'pending' //正在进行状态
const fulfilled = 'fulfilled' //成功状态
const rejected = 'rejected' //失败状态
class Promise {
constructor(executer){
this.status = pending //初始状态
this.data = '' //成功原因
this.reason = '' //失败原因
this.successFn = [] //成功回调
this.failedFn = [] //失败回调
const resolve = (data) => {
if(this.status === pending){
this.status = fulfilled
this.data = data
if(this.successFn.length > 0){
this.successFn.forEach((fn) => fn(this.data))
}
}
}
const reject = (reason) => {
if(this.status === pending){
this.status = rejected
this.reason = reason
if(this.failedFn.length > 0){
this.failedFn.forEach((fn) => fn(this.reason))
}
}
}
try(){
executer(resolve,reject)
}catch(e){
if(this.status === pending){
this.status = rejected
this.reason = e
}
}
}
//接受两个参数(resolved状态的回调函数,rejected状态的回调函数)
then(onSuceessFn,onFailFn){
onSuceessFn = typeOf onSuceessFn === "function" ? onSuceessFn : (val) => val
onFailFn = typeOf onFailFn === "function" ? onFailFn : (err) => {throw err}
//pending时
if(this.status === pending){
this.successFn.push(onSuceessFn)
this.failedFn.push(onFailFn)
}
//成功
if(this.status === fulfilled){
onSuceessFn(this.data)
}
//失败
if(this.status === rejected){
onFailFn(this.reason)
}
}
}
export default promise;
5. 异步控制并发数
function limitRequest(urls = [], limit = 5){
return new Promise( (resolve,reject) => {
const len = urls.length
let count = 0 //计数
const start = async () => {
const url = url.shift()
if(url){
try{
await axios.post(url)
if(count == len - 1){
resolve()
} else {
count++
start() //成功,开始下一任务
}
} catch (e) {
count++
start() //失败,也开始下一任务
}
}
}
while(limit > 0){
start()
limit -= 1
}
})
}
let urls = ['http://aaa.com', 'http://bbb.com', 'http://ccc.com', 'http://ddd.com', 'http://eee.com']
limitRequest(urls)