我想编写一个函数once
,该函数接受回调作为输入并返回一个函数。第一次调用返回的函数时,它应调用回调并返回该输出。如果再调用一次,则无需再次调用该回调,而只是从第一次调用时返回输出值。
以下是我尝试做的事情。但是我没有得到预期的结果。我需要了解这个概念。
function once(func) {
let num;
function retFunc(x){
num = func(x);
return num;
}
return retFunc;
}
function addByTwo(input){
return input + 2;
}
var onceFunc = once(addByTwo);
console.log(onceFunc(4)); //should log 6
console.log(onceFunc(10)); //should log 6
console.log(onceFunc(9001)); //should log 6
答案 0 :(得分:19)
仅应在num = func(x)
为num
时分配undefined
,即在第一次调用retFunc
时:
function once(func) {
let num;
function retFunc(x){
if (num === undefined) {
num = func(x);
}
return num;
}
return retFunc;
}
function addByTwo(input){
return input + 2;
}
var onceFunc = once(addByTwo);
console.log(onceFunc(4)); //should log 6
console.log(onceFunc(10)); //should log 6
console.log(onceFunc(9001)); //should log 6
但这不是保证的通用解决方案-如果调用时传递的函数(在您的示例中为addByTwo
)在undefined
中产生结果怎么办?然后,=== undefined
检查将不起作用。因此,最好设置一个标志或类似的东西,并在第一次调用回调时重新分配该标志:
function once(func) {
let num;
let done = false;
function retFunc(x){
if (!done) {
done = true;
num = func(x);
}
return num;
}
return retFunc;
}
function returnsUndefinedOn1(input){
return input === 1 ? undefined : input;
}
var onceFunc = once(returnsUndefinedOn1);
console.log(onceFunc(1));
console.log(onceFunc(10));
console.log(onceFunc(9001));
答案 1 :(得分:8)
仅应调用函数并分配num
(如果未定义),否则每次都将其覆盖:
function once(func) {
let num;
function retFunc(x) {
num = (num === undefined) ? func(x) : num
return num;
}
return retFunc;
}
function addByTwo(input) {
return input + 2;
}
var onceFunc = once(addByTwo);
console.log(onceFunc(4)); //should log 6
console.log(onceFunc(10)); //should log 6
console.log(onceFunc(9001)); //should log 6
请注意,如果传入的函数返回undefined
,则将多次调用该函数。如果需要处理这种情况,可以设置一个标志以指示缓存的值是否有效。
答案 2 :(得分:4)
您缺少的是在第一次执行后删除原始功能。您应该通过以下方式修改代码:
function once(func) {
let num;
function retFunc(x){
if (func)
num = func(x);
func = null;
return num;
}
return retFunc;
}
function addByTwo(input){
return input + 2;
}
var onceFunc = once(addByTwo);
console.log(onceFunc(4)); //should log 6
console.log(onceFunc(10)); //should log 6
console.log(onceFunc(9001)); //should log 6
这样,您在首次使用后删除该功能,而只是保留结果。
答案 3 :(得分:3)
这是你的问题
function retFunc(x){
num = func(x);
return num;
}
您总是在拨打func(x)
。添加if条件,以在调用num
之前检查undefined
是否为func(x)
。
答案 4 :(得分:2)
different approach: overwrite the call to func
no flags, check if result is undefined or anything required
function once(func) {
let num;
let internalFn = function(x) {
num = func(x);
internalFn = function(x) {
return num;
}
return num;
}
function retFunc(x){
return internalFn(x);
}
return retFunc;
}
function addByTwo(input){
return input + 2;
}
var onceFunc = once(addByTwo);
console.log(onceFunc(4)); //should log 6
console.log(onceFunc(10)); //should log 6
console.log(onceFunc(9001)); //should log 6