Comments (24)
i would be in favor of having them in the same module. when i use promised-io i use allKeys( ) more often than the array methods.
but no matter where they end up, i will be happy :)
from when.
Another namespacing option: when.keys.all()
, when.keys.reduce()
, etc. Not sure if "keys" is the right word there, but if we decide to put the key-based methods into the same module, I kind of like the idea of having a sub-namespace.
This also makes me wonder if it's possible to generate the keys methods from their corresponding array methods. I.e. is it possible to generate when.keys.all()
from when.all()
...
from when.
I like the separate module idea. If the key-ified module were to load when
as a dependency, you could use AMD path trickery:
curl({ packages: [ { name: 'when', location: 'path/to/when', main: 'when/keys' }); // or whatever method your AMD loader uses
define(['when'], function (when) {
when.keys.all(objectWithPromisesAsValues, doSomething);
});
from when.
Interesting idea. Are you thinking that when/keys
would load when
as a dependency, and then decorate it with a keys namespace and methods?
from when.
i like the namespace idea! but i'm also not sure if "keys" is the right word. when i discovered the allKeys( ) function in promised-io i had to look up the documentation because i had no clue about what that could be.
from when.
+1 for the namespace idea, it avoids cluttering the core when
API and would also all for orthogonality within the new module. I think keys
is a pretty good name; but maybe something like when.hashKeys.reduce()
is more descriptive - bit of a tricky one :)
from when.
Cool, thanks for the feedback on the namespace approach. It's probably the direction we'll ... just need to decide on a name :) Some other options:
- when.keys
- when.props or when.properties
- when.object
Other ideas?
from when.
Here's another option. What if when.all/any/some/map/reduce included a test to see if they are dealing with an array or an object, and just "did the right thing"? What are the pros and cons? Some initial thoughts:
Pros:
- Very easy to use: no need to require() another module, the functionality is always available in the core when module
- No need to think about which version of a method to call, e.g. when.all() vs. when.props.all(), just use when.all()
Cons:
- There's a potentially non-trivial code size hit (hundreds of bytes, most likely) if you don't need the object functionality. It will always be loaded.
- There's a very minor performance hit in each call to when.all/any/some/map/reduce to check for array vs. object. Honestly, this seems like a non-issue. Any async operation, like XHR, will dominate performance by many orders of magnitude.
- Potential risk of "oops": thinking you have an array when you have an object, and passing it to when.all() and it does something you didn't expect. Right now, this seems like a non-issue to me, too. If you think you have an array, and you really have an object, your code is probably broken anyway ;)
Thoughts?
from when.
I just pushed a branch that integrates object key support directly into when.all/any/some/map/reduce. So, you can pass an object or a promise for an object as the first param to any of the above methods, and it will operate on the object's keys/props. Arrays (and promises for arrays) should still all work as before (the unit tests say they do, anyway!)
I'm sure there are plenty of botches and edge cases I haven't covered, so the usual caveats apply :) Please try it out and let me know what you think of this versus potentially providing a separate module for object prop support.
from when.
Any reason this hasn't made it to the master?
from when.
Mostly because we've been focused on getting version 2.0 ready, and on other parts of cujo. I think we could probably get this into a 2.1 release. Do you have an immediate need for it?
from when.
We found it to be useful sometimes. We've implemented our own version, but
would be nice to have it available out of the box so to say. 2.1 sounds
good.
I wonder if this feature would overcomplicate things. I guess not, if you
think about it's quite intuitive in underscore.js to know when a certain
function will accept both an array and an object. It should be similar here.
On Mar 8, 2013 12:32 AM, "Brian Cavalier" [email protected] wrote:
Mostly because we've been focused on getting version 2.0 ready, and on
other parts of cujo. I think we could probably get this into a 2.1 release.
Do you have an immediate need for it?—
Reply to this email directly or view it on GitHubhttps://github.com//issues/30#issuecomment-14595848
.
from when.
Ok, cool. Yeah, I go back and forth on whether we should integrate it directly into when.all/etc. Lately, I've been feeling like single-purpose methods & functions are the way to go, so, at least right now, I feel like a separate when/keys
module with all
, map
, and reduce
methods would be a good path.
from when.
@KidkArolis You inspired me :) How does this look? ef1eccb
from when.
Nice! I'm not exactly sure why it's called when/keys
. Although, the only alternative I can think of is when/object
.
Also, how would you name this module in your code? I suppose:
var whenKeys = require("when/keys");
whenKeys.all({...});
from when.
Here's my thinking on the name when/keys. I considered a few names: when/keys, when/object, and when/props. I decided against when/props because I felt it should behave like Object.keys. Encouraging people to think of the object they pass to these new methods as a simple map or hash seems safer than allowing them to pass complex objects with deep prototype chains that may contain promises--that seems fraught with pitfalls to me.
I do like when/object, and it'd make a nice parallel if we ever extract the current array methods to a when/array module. There are 2 reasons I decided to go with when/keys over when/object. First, I think people will tend to name vars like the module name, i.e. var keys vs. var object, or var whenKeys (like you said) vs. var whenObject. Given that, to me, keys.all/map/reduce reads a bit more intuitively than object.all/map/reduce. I feel it communicates specifically that, for example, keys.map will map the keys of whatever you pass to it. Second, I feel it's important to imply that it will only map keys (i.e. own properties), and won't dig into the prototype chain. I think the name when/keys implies that more strongly than when/object.
All of that said, I'm def open to other names. I'm even open to rethinking the own props vs. prototype chain decision, if there are (very) compelling reasons.
from when.
Hmmm, does keys.reduce
actually make sense, given that a typical reduce/fold is ordered, and there is no officially required key enumeration order in EMCAScript? In practice, most engines use key insertion order, but there's no real reason it would be consistent.
I can still see it being useful, so maybe the right thing is just a BIG DISCLAIMER in the docs?
from when.
Thanks for sharing your thoughts! I like the naming of when/keys
now :)
I would consider removing keys.reduce though? I try to avoid relying on the order in such cases, why allow (encourage?) others to do it by providing this function. I don't think the behaviour is as consistent as you think in most engines, I'm sure I've seen some funky differences when you're adding/removing keys or using numeric keys or something, might be worth investigating more if it can lead to subtle bugs.
The prototype chain problem could be handled by a separate function when/keys/deepMap
? But I would try to avoid that too until someone asks for one.. :)
from when.
Yeah, the key ordering problem seems scary, and could cause some subtle and frustrating bugs. I know at least in Chrome there have been changes to the ordering, some of which involve differences around numeric keys, like you pointed out.
You've very nearly convinced me that forcing people to do something like keys.all(obj).then(function(resolvedMap) { Object.keys(resolvedMap).reduce(...); });
is the way to go.
I'll let it stew a bit, and see how I feel.
I agree about deepMap
. If someone presents a strong case for it, we can consider it in a separate issue.
from when.
Ugh, underscore and lodash both support reducing object keys :/
from when.
We could ask them why they think that's ok.
from when.
Ok, after a quick discussion with @unscriptable, and after reading this v8 issue, I'm convinced that, at least for now, keys.reduce
has too much potential for confusion. Reduce/fold is, by it's very nature an ordered operation: http://en.wikipedia.org/wiki/Fold_(higher-order_function). While something commutative, like addition or boolean and/or, will work fine with arbitrary order, something as simple as string concatenation is dangerous with non-deterministic ordering!
from when.
@unscriptable did end up asking @jdalton briefly about reduce(obj)
in lodash, and the general sense was that people weren't confused by it and tended not to use it for operations where non-deterministic key ordering was a problem. So maybe it's not a problem in practice.
Still, we'll probably launch 2.0 without it and happily add it later if people want (and understand the tradeoffs!)
from when.
The when/keys
module is released in when 2.0.0 with all
and map
. If folks have strong use cases for reduce
, we'll consider adding it (with the caveat listed above about key ordering)
from when.
Related Issues (20)
- Cannot resolve module 'vertx' HOT 9
- JSPM build (SystemJS builder) failing on [email protected] HOT 3
- Does not work in NodeJS (ReactJS Native) HOT 12
- Visual Studio debugger breakes from adding When to WebPack bundle. HOT 13
- 3.7.7 breakes the build on Windows HOT 2
- no such file or directory .... es6-shim/makePromise HOT 2
- Global rejection events completely broken in a bundled environment (eg. Webpack)
- When not working in Jasmine tests
- when.reduce UnhandledPromiseRejectionWarning HOT 4
- Misleading unhandled rejection warning when using when.settle HOT 10
- npm install ! has errors HOT 1
- Usage hello world example fails with TypeError HOT 3
- Binding context to promise chain HOT 2
- Add react-native support HOT 2
- File 404 when try to use in browser environment
- Promise.js first function never runs HOT 2
- RTE TypeError after production build HOT 4
- Does function call also accept promises? HOT 4
- Current project status HOT 1
- npm install failing with 404 error code
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from when.