2017-01-20 1 views
0

У меня есть следующие функции:Возвращаясь из анонимной функции не будет работать, даже если он не ASync

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)); 

Где твит определенный объект. Я вижу, что функция действительно возвращается, потому что я вижу вывод hello, im returning в консоли, но console.log(filterDesiredURLs(tweet)); печатает undefined. Я ожидал бы этого для анонимных функций, переданных как обратные вызовы для асинхронных операций, но это не async, поэтому возврат должен работать. Что происходит?

+0

Вы возвращения из внутренней функции, а не внешней функции. 'Array # forEach' игнорирует возвращаемое значение его обратного вызова. – 4castle

+0

Похоже, что ваш код должен использовать ['Array # filter'] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) и [' Array # some'] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some) вместо двух циклов 'forEach'. – 4castle

ответ

1

return не работает через границы функций. Он возвращается только от самой внутренней функции. Для того, чтобы делать то, что вы хотите, вы, вероятно, хотите filter или find в сочетании с 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']); 
    }); 
    }); 
} 
+0

Обратите внимание, что в зависимости от сложности вашего регулярного выражения по сравнению с * числом * из них он может * иметь больше смысла объединять все ваши регулярные выражения путем их объединения и тестирования с объединенным регулярным выражением один раз. Но это, скорее всего, микро-оптимизация. –

1

Когда вы вызываете return, вы возвращаетесь из ближайшей функции (в этом случае анонимная функция передается как аргумент вашему внутреннему forEach).

docs От:

Инструкция возврата заканчивает выполнение функции и определяет значение, которое должно быть возвращено к функции вызывающего абонента.

Для достижения своей цели, вы можете попробовать это:

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; 
} 
+1

'return;' не нарушит 'forEach', он просто выйдет из этой единственной итерации. Подумайте об этом как оператор 'continue;' в цикле 'for'. – 4castle

+0

@ 4castle, вы правы! tnks – mrlew

0

Javascript forEach метод возвращает undefined.

forEach - операция, которая сохраняет массив как неизменяемый и возвращает новый массив. В вашем коде вызывается метод forEach и он ничего не возвращает, следовательно undefined.

Смежные вопросы