封装一个只发送一次的网络请求函数

296 阅读1分钟

今天上班摸鱼水群的时候,看到群主推了一个问题,如何防止发送重复的网络请求? 这个在实际项目中也非常常见,于是自己动起手来。

下面这是模拟一个ajax请求的函数

let state = 0
function mockAjax(value){
    return new Promise((resolve,reject) => {
        setTimeout(() => {
            resolve(state += value)
        },1000)
    })
}`

这个请求的函数如果被多次执行,state的值会不断发生改变,这并不是我们所期望的,我们仅仅只想这个请求函数能多次执行,但是他只会发送一次请求(也就是仅仅修改一次state)

mockAjax(1).then(res => console.log(res)) //state = 1
mockAjax(1).then(res => console.log(res)) // state = 2
  • 这里使用高阶函数(高阶函数定义:函数的参数是函数或函数返回值是函数)
  • fn就是我们所期望的:仅发送一次网络请求的方法
function fetchWithNoRepeat(fn){
    //p保存当前状态
    let p = null
    return function(value){
        if(p){
            return p
        }else{
            p = fn.call(this,value)
            return p
        }
    }
}
let foo = fetchWithNoRepeat(mockAjax)(1)

fetchWithNoRepeat(mockAjax)得到一个新函数,接着执行新函数并传递参数fetchWithNoRepeat(mockAjax)(1),此时便已经模拟发送ajax请求了,如果他已经具有实例p则会直接返回,这也仅发送一次请求的原因。

最后返回的p是promise实例,用then去接受一下状态改变的回调。

foo.then(res => console.log(res)) //state = 1
foo.then(res => console.log(res))  //state = 1
foo.then(res => console.log(res))   //state = 1

the end, it's so cool , what do you think