当作为回调传递时,随着每个函数调用递增地返回每个数组项

Posted

技术标签:

【中文标题】当作为回调传递时,随着每个函数调用递增地返回每个数组项【英文标题】:Return each array item incrementally with each function call when passed as callback 【发布时间】:2022-01-19 01:48:56 【问题描述】:

我有一个对象数组,例如: [, , , , ]; 我还有一个递归函数,它接受一个函数作为参数:

function recursiveFunction(getResponse) 
   const result = getResponse();
   
   const conditionMet = check(result);

   if(conditionMet) 
      return result;
   

   return recursiveFunction(getResponse);
 

如何创建一个函数 getResponse,以便每次在 recursiveFunction 中调用它时,它都会返回我数组的下一次迭代?

例如,在每次递归时,它应该获取数组中的下一个对象:

function getResponse(index) 
   return array[index ++];

当我调用它时:

const firstIndex = -1; // Because index ++ in function
const result = recursiveFunction(getResponse(firstIndex));

我明白为什么它只返回第一个值,但我不确定如何修改它以在再次调用它时返回数组中的下一个索引。

【问题讨论】:

getResponse() 应该是包含当前数组索引和数组的环境中的闭包。它可以增加索引并返回该数组元素。 这似乎是一个家庭作业,所以不要索要代码。 我想我应该提供上下文。在我的例子中,recursiveFunction 是一个函数,它递归地调用一个 api 端点,然后在满足条件时最终返回(本质上是轮询同一个端点)。我正在尝试为该特定函数编写一个单元测试,而我的数组是响应的模拟,因此为什么我使用回调,所以我可以传入函数来发出 GET 请求并传入另一个函数,它只是返回我的模拟中的响应。 好的,这不是家庭作业。但是我们仍然希望您先尝试解决它,然后我们会帮助您解决它。 在 ES6 中,您可以在包含 let 数组和索引变量的块中创建一个函数。在 ES5 中,使用 IIFE 为变量创建环境。 【参考方案1】:

您应该将函数作为参数传递,而不是调用函数。

const result = recursiveFunction(getResponse);

另外,如果将索引初始化为-1,则需要使用++index,而不是index++

【讨论】:

【参考方案2】:

javascript 中执行此操作的方法是使用内置的 Iteration Protocol -

const myinput =
  [ a:1, b:2, c:3, d:4 ]
  
const it =
  myinput.values()
  
console.log(it.next())
console.log(it.next())
console.log(it.next())
console.log(it.next())
console.log(it.next())
value: a:1, done: false
value: b:2, done: false
value: c:3, done: false
value: d:4, done: false
value: undefined, done: true

您可以创建自己的 iter 函数,该函数返回一个与您描述的函数类似的函数 -

  
function iter(iterable) 
  const it = iterable.values()
  return () => it.next().value


const inputA = [1,2,3]
const inputB = ["a","b","c"]

const nextA = iter(inputA)
const nextB = iter(inputB)

console.log(nextA()) // 1
console.log(nextA()) // 2
console.log(nextB()) // "a"
console.log(nextB()) // "b'
console.log(nextA()) // 3
console.log(nextB()) // "c"
console.log(nextA()) // undefined
console.log(nextB()) // undefined

在您的程序中,您必须检查 undefined 才能知道何时没有剩余值 -

function recursiveCheck(check, getResponse) 
  const result = getResponse()
  if (result === undefined)
    return "not found"
  else if (check(result))
    return "condition met"
  else
    return recursiveCheck(check, getResponse)


const output = recursiveCheck(myChcek, iter([..., ..., ...]))

console.log(output)

在这种特殊情况下使用递归意味着您输入的大小将受到限制。如果你简单地使用for..of,你所有的问题都会消失-

function iterativeCheck(check, iterable) 
  for (const result of iterable)
    if (check(result))
      return "condition met"
  return "not found"


const output = iterativeCheck(myCheck, [..., ..., ..., ...])

console.log(output)

另请参阅Symbol.asyncIterator,了解如何将这种方法用于异步迭代。

【讨论】:

以上是关于当作为回调传递时,随着每个函数调用递增地返回每个数组项的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中传递和存储闭包/回调

回调函数的使用。

设计一个函数,它接受不定数量的参数,这是参数都是函数。这些函数都接受一个回调函数作为参数,按照回调函数被调用的顺序返回函数名

在传递给函数之前,for循环递增到限制

js中filter函数

当作为参数传递给返回 void 并在函数中修改的函数时,如何修改 Java ArrayList?可能对按值传递感到困惑