实现一个 once 函数,记忆返回结果只执行一次
更多描述 类似于
lodash.once
const f = (x) => x;
const onceF = once(f);
//=> 3
onceF(3);
//=> 3
onceF(4);
Issue 欢迎在 Gtihub Issue 中回答此问题: Issue 406 (opens in a new tab)
Author 回答者: shfshanyue (opens in a new tab)
简单实现如下:
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 (opens in a new tab) 是社区使用最广泛的一个库,代码实现与上大同小异,然而每月下载量可达上亿,比 vue/react/angular 三者一个月的下载量加起来还要高一倍
Author 回答者: Vi-jay (opens in a new tab)
function onceCache(fn) {
let toggle = false,
ret = null;
return function () {
if (toggle) return ret;
toggle = true;
return (ret = fn.apply(this, arguments));
};
}
Author 回答者: eva-asdf (opens in a new tab)
惰性函数
function once(fn) {
function o(...args) {
const res = fn(...args);
o = () => res;
return o();
}
return o;
}
Author 回答者: plutda (opens in a new tab)
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