【问题标题】:How to break from inside a callback in a for-loop如何从 for 循环中的回调内部中断
【发布时间】:2018-09-27 18:51:18
【问题描述】:

如果我在javascript中bind函数find,我可以执行以下操作:

const _array = [4,10,6,5,20];

const loop = Array.prototype.find.bind(_array);
const r = loop(function (x) {
    return x === 6;
});

console.log(`Final result => ${r}`); // here prints: Final result => 6

如您所见,在 binded loop 函数中,我有一个从 find 返回的 回调。一切正常,没关系...

但是,试图模拟类似的东西,我以这个结尾:

function loop(a,callback) {
    for(i=0;i<a.length;i++)
        callback(a[i]);
};

const r = loop([4,10,6,5,20], function (x) {
    console.log("x value", x);
    return x===6; // need to break the loop function and return to 'r' the 'x' value
});

console.log(`Final result => ${r}`); // here would print the value of x, that would be 6

我得到:

x value 4
x value 10
x value 6
x value 5
x value 20
undefined

什么意思是r函数里面的return x===6不能正常工作,因为for-loop一直到最后。

那么,我的问题:

x===6 时如何破坏loop 函数并返回x 的值?

【问题讨论】:

  • 呃,你的loop 函数的行为类似于forEach,而不是find
  • @Bergi 这就是我问的原因。
  • 所以你实际上是在问“How to implement find我自己?”,对吧?
  • @Bergi 不完全是,我只是以find 函数为例,但我的问题是关于如何从for-loop 内部的回调中返回。就是这样。
  • 这个问题的答案是:一般情况下你不能。回调不控制它被调用的频率或loop 返回的内容,它也不能只是“跳出”控制流(除非您正在考虑异常,但即使是那些也可以被捕获)。唯一的办法就是让loop函数对回调调用的返回值做出反应。

标签: javascript node.js for-loop callback


【解决方案1】:

查看回调返回什么值,然后决定是否继续:

function loop(a, callback) {
  for (let i = 0; i < a.length; i++) {
    const found = callback(a[i]);
    if (found) {
      return a[i];
    }
  }
}

const r = loop([4,10,6,5,20], function (x) {
  console.log("x value", x);
  return x===6;
});

console.log(`Final result => ${r}`);

【讨论】:

  • function loop (a, callback) { for (const value of a) if (callback(value)) return value }
  • 是的,当然,就是这样。谢谢!
  • @PatrickRoberts 不错,如果你把它写成答案,我会投赞成票!
  • @robe007 这与这个答案真的没有什么不同,这就是为什么我把它放在评论中。它只是更简洁一点。
【解决方案2】:

你也可以用递归写find

const find = (f, [ x, ...xs ]) =>
  x === undefined
    ? null
  : f (x) === true
    ? x
  : find (f, xs)

console.log
  ( find
      ( x => x > 8
      , [ 5, 7, 9, 3, 1 ]
      )
      // 9
      
  , find
      ( x => x < 4
      , [ 5, 7, 9, 3, 1 ]
      )
      // 3
  )

可以使用索引参数代替解构赋值

const find = (f, xs = [], i = 0) =>
  i >= xs.length
    ? null
  : f (xs[i]) === true
    ? xs[i]
  : find (f, xs, i + 1)

在这两种情况下,只要 f 返回 true,对数组的迭代就会停止

【讨论】:

  • 我认为您的参数需要交换。问题中的array 是第一个参数,而不是第二个。另外递归对于大数组会导致栈溢出错误,所以不推荐这种方式。
  • PS 有many ways 以避免堆栈溢出
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-07
  • 2020-04-08
  • 2013-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多