Skip to content
This repository has been archived by the owner on Mar 25, 2018. It is now read-only.

What about the co approach? #1

Open
mikeal opened this issue Feb 24, 2015 · 10 comments
Open

What about the co approach? #1

mikeal opened this issue Feb 24, 2015 · 10 comments

Comments

@mikeal
Copy link
Contributor

mikeal commented Feb 24, 2015

Recently co moved to using promises, or more specifically yielding promises.

https://github.com/tj/co

There's been talk of having APIs in NG return promises. What are the downsides/upsides of return vs. yield?

@mikeal
Copy link
Contributor Author

mikeal commented Feb 24, 2015

@domenic probably has things to say.

@domenic
Copy link

domenic commented Feb 24, 2015

This is a false dilemma. All functions would return promises. Consumers could consume them either with:

  • .then directly
  • yield, if inside a wrapper function like co() or Q.spawn() or Bluebird.async()
  • await, if inside an ES2016 async function.

yield is kind of a hack in this way, but a cool one. By wrapping your generator function in co() or whatever, you make yield inside your generator function no longer yield items in a lazy sequence, but instead do control-flow stuff. async + await is the more principled version of this.

A more interesting question is whether NG would want to provide a standard co()/spawn()/async() function or set of functions, as a sort of polyfill for async functions. Seems pretty OK.

@rauchg
Copy link

rauchg commented Feb 24, 2015

Personally I don't like the generator hack as first-class thing. It's primarily a good compilation target / temporary implementation of await.

The first goal for NG should be to return a Promise every time async work is done. That's sufficient in the short term. It enables composition, paves the way for the future, and enables fairly straightforward transpilation in the mean time (specially now with generators enabled by default).

@gobengo
Copy link

gobengo commented Feb 27, 2015

+1 to @rauchg

IMHO first goal should just be to release a version that replaces stdlib errbacks with returning Promises. There are lots of errbacks in the node stdlib, so that's a lot of sheds to paint in a first pass anyway.

Promises instead of errbacks are an important improvement because it makes 'throw' and 'return' useful again.

You still get crazy 'then' chains instead of pyramids of doom, and that is where async/await and async functions can help. See: http://jakearchibald.com/2014/es7-async-functions/

But to your question of "What are the downsides/upsides of return vs. yield?". Yield provides a path to 'return' several times

Once ES2016, the only time I expect to write yield directly is when creating readable-stream-like things. e.g.

async function * longPollSocket({ url, initialEventId }) {
  let eventId = initialEventId;
  while (let res = await fetch(url + '?since='+eventId)) {
    eventId = res.body.eventId;
    let msg = res.body.data;
    yield msg;
  }
}

// iterates async..
for (var msg on longPollSocket(opts)) {
    console.log('msg after some time');
}

(inspired by jhusain/asyncgenerator)

Notably, co inherently doesn't really try to help you take advantage of this aspect of Generators (multiple, yields). By returning a promise of a single value that is resolved only once all the yields in your generator are done, it's gives up on any potential of multiple async events.

@benjamingr
Copy link
Member

@gobengo this is because promises represent a single value. You can yield multiple values though:

let [r1, r2] = yield Promise.all([p1, p2]);

For example. I agree with Domenic - a co like approach is just returning promises :)

@bmeck
Copy link
Member

bmeck commented Apr 7, 2015

@balupton
Copy link

balupton commented Apr 8, 2015

Isn't the beauty of the callback/errback approach is that it works with any other abstraction people want to apply to it? This would turn node core from a low level utility belt, to an opinionated thing - I kind of like it how if we want promises for the fs module, we just install a package and now I have promises for fs.

What are the gains of switching from errbacks?

@petkaantonov
Copy link

@balupton not at all. First of all, you can convert any api that follows some sort of standard or convention automatically to something else. Secondly callbacks do not follow any single standard or convention, not even within node core itself and especially not in the wild.

@trevnorris
Copy link

I'm currently working on a standardized low-level API for Node as part of a future API Compliance WG. My plan is that the current API will be built on top of this, also allowing simple interface extensions in the future. Basically, I'm not against including a Promise based interface for the API, but it won't be the interface directly into C++.

@jonathanong
Copy link

+1 return promises everywhere!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants