缓存其参数的返回值的函数

时间:2019-01-07 07:22:50

标签: javascript memoization

我想编写一个函数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

5 个答案:

答案 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