-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Feature request - autoInjectReturnResults #1122
Comments
I'm not sure how I feel about this function depending on the names of parameters. Seems quite sketchy to me. I think I'm 👎 including this in core. Rather than forking, I would recommend you create a library exporting this function so you could do
/cc @aearly |
Ha! I'm not sure how or why parameter names would change unless you mean the name of the function itself which I can only agree stinks. I am curious to know how I could easily just create a library. I'm likely missing something but I tried to do this by defining my new 'sketchy' function which involved copy/paste from async then aforementioned modification to replace the call to |
Minification can change parameter names, as you mentioned in the comments
Unless I'm misunderstanding, you can import the same lodash methods and import auto from 'async/auto';
import forOwn from 'lodash/forOwn';
import arrayMap from 'lodash/_arrayMap';
import clone from 'lodash/_copyArray';
import isArray from 'lodash/isArray';
export default function autoInject(tasks, callback) {
...
} |
Yep, relying on param names is no good. |
@jdalton @megawac - Yeah I realize that we could have a religious war about use of param names by @megawac thanks for the suggestion I'll take a look! The hurdle will be that our nodejs project doesn't currently use ES6. We've been thinking of moving in that direction for a variety of reasons. I don't think this will push us over the cusp but it'll continue to build the case for it. |
@darrin you can easily replace ES6 with commonJS var auto = require('async/auto');
var forOwn = require('lodash/forOwn')
var arrayMap = require('lodash/_arrayMap');
....
module.exports function autoInject(tasks, callback) {
...
} |
Nothing religious about it. It breaks when minified so it's a non-starter. |
@jdalton - The writer of @megawac thanks - I'll give that a shot. Definitely agree I'd like to get away from the fork. |
The original original author (@steverobb) of |
Well - I do understand why you did it. There is a symmetry to the current I'm not the most objective to argue the case for changing it back BUT of
|
As the author of the original feature, I'm not the most objective to argue the case for leaving it as it is BUT of course I think you should. ;) One of the aims of autoInject was to give a very clear picture of dependencies throughout the construction of the task graph. This is a readability and maintenance win. I do see your need though - even if you don't do the sketchy thing of relying on parameter names, I can see it being useful to have packed results for ease of passing around, so there's no point in autoInject unpacking them only for you to repack them. However, auto already gives you that, so you could just use that instead of autoInject. I guess that's not desirable either? I originally tried to fold the packing/unpacking behaviour into auto. I considered reserving a 'results' parameter name (and 'callback') to make that work, but that seemed terrible. In the end, it just seemed a lot easier to create a new function rather than overload auto further. tl;dr: I think autoInject should stay as it is. I think a new function like autoInjectReturnResults is reasonable to have. |
@steverobb Thanks so much for contributing your thinking here and for writing Yes, the readability and maintenance win is what I'm going for here. I think it's worth it to try to convince you that the original way you wrote it is worth sticking with. An (admittedly contrived) example would help me explain why I think what we're calling Let's assume we want to calculate some series of logical statements. Further assume we want to be able to say WHY any given statement was true or false so we really want all the calculated dependencies back. Assume there are many dependencies for some functions. Lastly the statements are likely to change over time as we add new logic - so we know we'll have to manage changes to the code. Below I'll show 3 examples - one for each approach. I'm highlighting a more complex function definition ('g' in this case) and leaving the others out. Also I'm assuming that we leverage parameter names for mapping - (I don't care or need minification in my use-case) - so I'm using the abbreviated syntax: With
|
You really didn't need to write a book - as I already said, I agree with your argument for your use case. I just don't think your and my use cases are mutually exclusive. And I don't personally agree that having to list your result dependencies explicitly is objectively a negative - maybe it is in your case, but it certainly isn't in mine. A results object makes much of my code less terse and less readable. Explicitness of dependencies is part of the reason why I wrote autoInject in the first place: for clarity of reading dependencies so that obsolete (and thus removable) subgraphs can be quickly inferred during maintenance. Ultimately, it's not my library, so @aearly can choose to go with his preferred implementation (and he has already suggested a preference for composite results). If he chooses to go that way instead of yet another auto variant, then I could change my graphs to the following to make them slightly worse but still explicit:
|
I've been experimenting with my workaround above and I feel that it makes some of my graphs slightly less readable and others slightly more readable. A net lack of change in overall readability. As I still get my explicit dependencies and the tide seems to be in favour of composite results, I'm fine with reverting this back, so I have: #1126 Hopefully everyone now wins. :-) People might still expect the final callback to be injected, as per @darrin's first 'con' for autoInjectReturnResults above, but perhaps that's just a documentation issue. |
Yeah, after giving this more thought, I like returning a result object, rather than injecting individual results. By default, the final callback omits data -- it would be better if The minification issue still exists, and though you can work around it by passing an array with the param names as strings, it's still odd to not have a plain callback function as the last arg. |
Closed by #1126 |
First - thanks for async - it's just awesome! I think I love you guys.
What's more - I'm loving the autoInject function. I have some generic code where I build the set of tasks dynamically - it all works swimmingly with autoInject. However - the code doesn't need a single result or a small subset. Nope, I need the full set of task results - ideally in a map just like
auto
would return.I'm currently forking async (darrin/async) to accomplish this. I've created a new function called
autoInjectReturnResults
that does what I want. The only difference between it andautoInject
is that I pass the callback straight-through toauto
after theforOwn
block here with this:Unless I was under the influence I think an early implementation of autoInject as working exactly this way. I'm certain it was changed because this is a bit inconsistent and maybe non-intuitive unless you really know you want this behavior.
Anyone have thoughts on this? Am I the only one that needs to know the full set of task results without knowing apriori what the task names will be?
Thanks in advance,
-Darrin
The text was updated successfully, but these errors were encountered: