javaScript常见手写算法题(前端笔记二)

本文介绍了JavaScript中的性能优化技术,包括防抖和节流函数的实现,用于优化事件处理函数的执行;展示了大数相加的算法,以及手写Promise的简化版本,最后讨论了如何限制并发请求的数量来优化异步操作。
摘要由CSDN通过智能技术生成

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)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值