# 高阶函数

# 惰性函数

执行一次修改函数,让以后的调用都执行修改后的函数,使用场景如浏览器兼容判断。
浏览器兼容判断在浏览器运行的时候就可以判断,浏览器运行时通过兼容性判断,决定以后使用什么函数

# 基本思想

创建一个函数,让这个函数返回一个兼容该浏览器的函数,从此在该浏览器下就一直调用该函数

//创建一个生成函数的函数
const creatfun = (type) => {
    if (type) return () => {
        console.log('这是type为true时返回的函数')
    }
    else return () => {
        console.log('这是type为false时返回的函数'
    }
}
//在页面开始挂载时就可以调用该函数 将该函数返回的函数保存在变量中 
const fun = creatfun()
//以后就可以直接调用该函数
fun()

# 并发任务控制

const timeOut = (time) => {
    return new Promise((res, rej) => {
        setTimeout(() => {
            res()
        }, time)
    })
}

class SuperTask {
    parallelCount: number;
    taskArr: [];
    runingTask: number;

    constructor(parallelCount = 1) {
        this.parallelCount = parallelCount//并发数量
        this.taskArr = []//任务队列数组
        this.runingTask = 0//正在运行的任务数量
    }

    add(task) {
        return new Promise((res, rej) => {
            this.taskArr.push({res, rej, task})
            this._run()
        })
    }

//执行任务
    _run() {
        while (this.runingTask < this.parallelCount && this.taskArr.length > 0) {
            const {res, rej, task} = this.taskArr.shift()
            this.runingTask++
            task().then(res, rej).finally(() => {
                this.runingTask--
                this._run()
            })
        }
    }
}

const superTask = new SuperTask()
const addTask = (time, name) => {
    superTask.add(() => timeOut(time))
        .then(() => {
            console.log(`任务${name}完成`)
        })
}
addTask(1000, 1)
addTask(1000, 2)
addTask(1000, 3)
addTask(1000, 4)
addTask(1000, 5)
addTask(1000, 6)

# 带参数的计算属性

vue中的计算属性是不能携带参数
需求 计算属性是一个带缓存的函数 如有缓存则直接返回缓存结果 如没有缓存则计算后结果存入缓存再返回结果

# 基本思想:

  1. 编写一个函数 这个函数需要传入一个函数并且返回一个函数
  2. 传入的函数会在此函数中选择性调用 即有缓存结果时直接返回结果 没有缓存才调用传入函数 并存入缓存返回结果

# 难点

判断是否具有缓存

  • 可使用map数据类型存入缓存 map中的以键值对的形式存在,key可以是对象或数组 因此可以把传入函数的对象或数组作为map 中的key,最终计算结果保存为map中的value
  • map中的value可使用计算属性存入 目的是利用计算属性来动态计算
  • 在判断是否具有缓存的操作时,最终是对比map中是否存在相同的key如果存在则证明有缓存
  • 判断是否存在相同key时,应该考虑nullundefine的情况,所有适合使用Object.is方法

# 函数编写

//可传参的计算属性
export const useCompontent = (fn: (...args: any) => void) => {
    const cache = new Map()
    //浅比较两个值
    const equal = (arr1, arr2) => {
        const result = arr1.length === arr2.length && arr1.every((item, index) => Object.is(item, arr2[index]))
        return result
    }
    //根据缓存结果key返回缓存结果
    const getCache = (args) => {
        const keys = [...cache.keys()]
        const key = keys.find((item) => equal(item, args))
        if (key) return cache.get(key)
    }
    return (...args) => {
        //有缓存返回缓存结果
        const cacheResult = getCache(args)
        if (cacheResult) {
            return cacheResult.value
        }
        //没有缓存 调用函数 存入缓存 返回结果
        const result = computed(() => fn(...args))
        cache.set(args, result)
        return result.value
    }
}

# 使用

//可传参的计算属性测试
import {useCompontent} from './constant'

const compoent = (value: any) => {
    console.log('computed 归档')
    return value?.isFile === 1
}

const isFileFun = useCompontent(compoent)
const isFile = computed(() => isFileFun(toRaw(selectedRow.value)))
上次更新: 9/4/2023, 11:59:10 AM