Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why won't yield return from within a `.map` callback? #1186

Closed
gyaresu opened this issue May 28, 2015 · 8 comments
Closed

Why won't yield return from within a `.map` callback? #1186

gyaresu opened this issue May 28, 2015 · 8 comments

Comments

@gyaresu
Copy link
Member

@gyaresu gyaresu commented May 28, 2015

Learn Generators - 4 » CATCH ERROR!
The solution uses a for loop but I just couldn't find anything MDN - Iteration Protocols that refers to yield within callbacks.

I'm going to guess the answer is just don't do that but thanks in advance if anyone has the time or inclination to provide an explanation!

Code:

function *upper (items) {
  items.map(function (item) {
    try {
      yield item.toUpperCase()
    } catch (e) {
      yield 'null'
    }
  }
}

var badItems = ['a', 'B', 1, 'c']

for (var item of upper(badItems)) {
  console.log(item)
}
// want to log: A, B, null, C

Error:

⇒  learn-generators run catch-error-map.js
/Users/gyaresu/programming/projects/nodeschool/learn-generators/catch-error-map.js:4
      yield item.toUpperCase() // error below
            ^^^^
SyntaxError: Unexpected identifier
    at exports.runInThisContext (vm.js:73:16)
    at Module._compile (module.js:443:25)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Function.Module.runMain (module.js:501:10)
    at startup (node.js:129:16)
    at node.js:814:3

Even my editor knows this is a terrible idea...

yield within callback

@martinheidegger
Copy link
Contributor

@martinheidegger martinheidegger commented May 28, 2015

@marocchino
Copy link
Member

@marocchino marocchino commented May 28, 2015

You mean @isRuslan ?

@marocchino
Copy link
Member

@marocchino marocchino commented May 28, 2015

BTW, If you want to use Array.map you can do like this:

function *upper (items) {
  yield* items.map(function (item) {
    try {
      return item.toUpperCase()
    } catch (e) {
      return null
    }
  })
}
@gyaresu
Copy link
Member Author

@gyaresu gyaresu commented May 28, 2015

I started a question on Stack Overflow: Why won't yield return from within a .map callback?

I hope that's not bad form

@isRuslan
Copy link

@isRuslan isRuslan commented May 28, 2015

Hi everyone. What a good question. 👍

Yes, MDN - Iteration Protocol doesn't refer directly about yield within callbacks.
But, it tell us about importance from where you yield item, because you can only use yield inside generators. See MDN - Iterables docs to find out more.

@marocchino suggest just fine solution iterate over Array that was changed after map. We can do it, because Array has iteration mechanism, see [Array.prototype@@iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/@@iterator).

var bad_items = ['a', 'B', 1, 'c'];

for (let item of bad_items) {
  console.log(item); // a B 1 c
}

Array.prototype.map doesn't have default iteration behavior, so we couldn't iterate through it.

But generators is not just iterators. Every generator is an iterator, but not vice versa. Generators allows you to customize iteration (and not only) process by calling yield keyword. You can play and see the difference between generators/iterators in babel/repl.

@gyaresu
Copy link
Member Author

@gyaresu gyaresu commented May 28, 2015

Wow. @marocchino & @isRuslan

Thanks so much for a fantastic solution and explanation! Closing issue.

@gyaresu gyaresu closed this May 28, 2015
@isRuslan
Copy link

@isRuslan isRuslan commented May 28, 2015

Should it be cross-posted to StackOverflow? But answer by slebetman is kinda correct also.

@gyaresu
Copy link
Member Author

@gyaresu gyaresu commented May 28, 2015

@isRuslan I think you should definitely post a solution to SO. I just want the knowledge out there not the points :)

edit: I've removed my comments on the SO post.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants