关于延迟函数的一点记录

374 阅读2分钟

前言

在前端面试中,相信绝大部分人都碰到过这问题

面试官: 请你实现一个延迟触发函数

你: 这还不简单

setTimeout(function(){
    axios.post(xxx, res => {
        console.log(res)
    })
}, 1000)

这时候面试官可能会跟你说:还有别的实现方法吗? 心里可能早就哔哔哔各种人工消音在崩腾了.

这里我记录下我自己碰到的问题和再项目中碰到的问题

思路

1.1版本

这个版本我们只需要写出一个最基本的延迟接触方法,形式跟上面让面试官哔哔那个差不多,但是是用es6的promise来写

new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve()
    }, 1000)
})

上面就是一个基于es6 promise 最基本的延迟返回方法,下面我们来封装成一个函数,并把延迟时间交由用户输入

1.1.1 版本

const deplay = (ms) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve()
        }, ms)
    })
}

这时候面试官可能又会问你了,这函数延迟是可以了,那我能不能在此基础让函数直接失败,并返回我所传的值呢?

image

这时候,一咬笔,一转笔,思路突如泉涌啊,既然想着了,咱就写

1.2版本

const deplay = (ms, {value, willResolve} = {}) => {
    return new Promise((resolve, reject) => {
        setTimeou(() => {
            if (withReject) {
                resolve(value)
            } else {
                reject(value)
            }
        }, msg)
    })
}

这时候,你就可以斜着眼有点傲娇的看着面试官,意思就像: 小样,你继续呀

这时,面试官看你这傲娇样,歪着脑袋一想: 这小伙子有点看来差不多是个合适的初级前端了,看来得稍微再上升点.

image

面试官: 现在这个函数我想提前清除函数怎么弄呢

1.3 清除版本

const createDelay = ({willResolve}) => (ms, {value}  {}) => {
    let timeoutKey;
    let settle;
    const delayPromise = new Promise((resolve, rejece) => {
        settle = () => {
            if (willResolve) {
                resolve(value)
            } else {
                reject(value)
            }
        }
        timeoutKey = setTimeout(settle, ms)
    })
    
    // 清除函数
    
    delayPromise.clear = () => {
        // 清除定时器
        clearTimeout(timeoutId);
        // 定时器置为空
        tiemoutKey = null
        // 触发成功/失败函数
        settle();
        
    }
    return deplayPromise
}

// 创建使用函数
const createTimers = () => {
    conse delay = createDelay({willResolve: true});
    deplay.reject = createDelay({willResolve: false})
    return delay;
}

// 使用
const deplayFn = createTimers();

参考

面试官:请手写一个带取消功能的延迟函数,axios 取消功能的原理是什么

deply-github仓库github.com/sindresorhu…

结尾

延迟函数说简单也简单,用一个setTimeout就搞定,说复杂也复杂,你可以再函数里面封装各种方法,比如提前清除、触发取消、自定义clearTimeout 和setTime函数等,这次先记录到这里,后续会继续在这里补充

image