【问题标题】:Returning from an anonymous function won't work, even though it's not async从匿名函数返回不起作用,即使它不是异步的
【发布时间】:2017-01-20 04:15:08
【问题描述】:

我有以下功能:

function filterDesiredURLs(tweet) {
    tweet.entities.urls.forEach((url) => {
        desiredURLs.forEach((regexPattern) => {
            if (regexPattern.test(url['expanded_url'])) {
                console.log('hello, im returning');
                return true;
            }
        })
    })
}

我这样称呼它:

console.log(filterDesiredURLs(tweet));

其中 tweet 是一个已定义的对象。我可以看到该函数确实正在返回,因为我在控制台中看到了输出 hello, im returning,但 console.log(filterDesiredURLs(tweet));prints undefined。我希望匿名函数作为异步操作的回调传递,但这不是异步的,所以返回应该有效。发生了什么事?

【问题讨论】:

  • 您是从内部函数返回的,而不是外部函数。 Array#forEach 忽略其回调的返回值。
  • 看起来您的代码应该使用 Array#filterArray#some 而不是两个 forEach 循环。

标签: javascript asynchronous return anonymous-function


【解决方案1】:

return 不跨函数边界运行。它只从 innermost 函数返回。做你想做的事,你可能想要filterfind 加上some

function filterDesiredURLs(tweet) {
  // First, you were missing a return in the outer function
  // Without a return here, *this* function will return `undefined`
  return tweet.entities.urls.filter(url => {
    // We are using `filter` to reduce the URL list to only
    // URLs that pass our test - this inner function needs to return
    // a boolean (true to include the URL, false to exclude it)
    return desiredURLs.some(regexPattern => {
      // Finally, we use `some` to see if any of the regex patterns match
      // This method returns a boolean value. If the function passed to it ever 
      // returns true, it terminates the loop and returns true
      // Otherwise, it iterates over the entire array and returns false.
      return regexPattern.test(url['expanded_url']);
    });
  });
}

【讨论】:

  • 请注意,根据您的正则表达式的复杂性与它们的数量,它可能通过以下方式组合所有正则表达式更有意义将它们“或”在一起并使用组合的正则表达式进行一次测试。但这可能是一个微优化。
【解决方案2】:

当您像这样调用return 时,您将从最近的函数返回(在这种情况下,匿名函数作为参数传递给您的内部forEach)。

来自docs

return 语句结束函数执行并指定一个值 返回给函数调用者。

为了实现你的目标,你可以试试这个:

function filterDesiredURLs(tweet) {
    let found = false;
    tweet.entities.urls.forEach((url) => {
        desiredURLs.forEach((regexPattern) => {
            if (regexPattern.test(url['expanded_url'])) {
                console.log('hello, im returning');
                found = true;
                /* don't need return because forEach does not expects a function that returns something; and you can't break forEach */
            }
        })
    })
    return found;
}

【讨论】:

  • return; 不会破坏forEach,它只会退出该单次迭代。可以把它想象成 for 循环中的 continue; 语句。
【解决方案3】:

javascript forEach 方法返回undefined

forEach 是一个操作,它将数组保留为不可变并返回一个新数组。在您的代码中,forEach 方法被调用并且它不返回任何东西,因此undefined

【讨论】:

    猜你喜欢
    • 2011-05-20
    • 2018-03-03
    • 2019-09-12
    • 2018-09-17
    • 1970-01-01
    • 2021-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多