Daily-Question icon indicating copy to clipboard operation
Daily-Question copied to clipboard

【Q399】实现一个 once 函数,记忆返回结果只执行一次

Open shfshanyue opened this issue 5 years ago • 5 comments

类似于 lodash.once

const f = x => x

const onceF = once(f)

//=> 3
onceF(3)

//=> 3
onceF(4)

shfshanyue avatar Aug 18 '20 03:08 shfshanyue

简单实现如下:

function once (f) {
  let result
  let revoked = false
  
  return (...args) => {
    if (revoked) return result
    const r = f(...args)
    revoked = true
    result = r
    return r
  }
}

测试一下

> const f = () => {console.log('call'); return 3;}
< undefined

> once_f = once(f)
< (...args) => {
    if (revoked) return result
    const r = f(...args)
    revoked = true
    result = r
  }

// 第一次调用
> once_f()
< call
< 3

// 第二次调用,没有打印 call
> once_f()
< 3

once 是社区使用最广泛的一个库,代码实现与上大同小异,然而每月下载量可达上亿,比 vue/react/angular 三者一个月的下载量加起来还要高一倍

shfshanyue avatar Aug 18 '20 14:08 shfshanyue

function onceCache(fn) {
  let toggle = false,
    ret = null;
  return function () {
    if (toggle) return ret;
    toggle = true;
    return (ret = fn.apply(this, arguments));
  };
}

Vi-jay avatar May 12 '22 02:05 Vi-jay

惰性函数

function once(fn) {
  function o(...args) {
    const res = fn(...args)
    o = () => res
    return o()
  }
  return o
}

eva-asdf avatar Jan 31 '23 14:01 eva-asdf

function once(func) {
    let revoke = false
    let ret = null
    return function() {
        if (!revoke) {
            ret = func.apply(this, arguments)
            revoke = true
        }
        return ret
    }
}

// 测试
function test() {
    console.log('test')
    return 1
}

let o = once(test)

console.log(o()) // test 1
console.log(o()) // 1
console.log(o()) // 1

plutda avatar Sep 19 '23 14:09 plutda