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

Comments

Projects
None yet
4 participants
@gyaresu
Member

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

This comment has been minimized.

Contributor

martinheidegger commented May 28, 2015

@marocchino

This comment has been minimized.

Member

marocchino commented May 28, 2015

You mean @isRuslan ?

@marocchino

This comment has been minimized.

Member

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

This comment has been minimized.

Member

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

This comment has been minimized.

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

This comment has been minimized.

Member

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

This comment has been minimized.

isRuslan commented May 28, 2015

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

@gyaresu

This comment has been minimized.

Member

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