Conversation
|
Also, I ran the benchmarks -- there is no difference in performance, whether the environment supports async functions or not. |
| # - node_js: "6" | ||
| # addons: | ||
| # firefox: "49.0" | ||
| # env: BROWSER=true MAKE_TEST=true |
There was a problem hiding this comment.
why are we disabling this stuff? Can we just up the firefox version?
There was a problem hiding this comment.
I disabled this thinking it was an issue with karma, but it's a syntax error. I'll investigate further and re-enable. We could test both 45 (ESR, no async support) and 52 (async supported).
| newTasks[key] = params.concat(params.length > 0 ? newTask : taskFn); | ||
| } else if (taskFn.length === 1) { | ||
| } else if ((!fnIsAsync && taskFn.length === 1) || | ||
| (fnIsAsync && taskFn.length === 0)) { |
There was a problem hiding this comment.
fnIsAsync + taskFn.length === 1 =P (dont do it lol)
There was a problem hiding this comment.
Actually, I should probably factor this condition out into a hasNoDeps variable.
| @@ -19,7 +20,7 @@ import onlyOnce from './internal/onlyOnce'; | |||
| * passes. The function is passed a `callback(err)`, which must be called once | |||
| * it has completed with an optional `err` argument. Invoked with (callback). | |||
| * @param {Function} test - synchronous truth test to perform after each | |||
There was a problem hiding this comment.
Is there a AsyncFunction jsdoc tag?
There was a problem hiding this comment.
I was thinking about the best way to document this. For sure, add something to the intro.md, but we have lots of repeated docs where we describe the iteratee function as a node-style async function. It would be nice to centralize the description of what Async accepts, with each Async method just describing the non-callback parameters.
There was a problem hiding this comment.
Perhaps an external definition if jsdoc doesn't support some way of documenting an async function?
There was a problem hiding this comment.
I'm also thinking of using a @typedef, like we do for the return values of queue/cargo.
There was a problem hiding this comment.
I really don't like how the @typedefs look in our code. I'd rather just link to MDN
There was a problem hiding this comment.
Check the latest commit. It's cleaner than the JSDoc docs make it out to be...
There was a problem hiding this comment.
👍 for using typedef for this. Does this mean most of the docs should to be updated to reflect that iteratee should be an AsyncFunction type?
There was a problem hiding this comment.
Yes, lots of docs to update. 😓 It does create a nice link to the central AsyncFunction docs in the rendered docs, though.
| var go = initialParams(function(args, callback) { | ||
| var that = this; | ||
| return eachfn(fns, function (fn, cb) { | ||
| return eachfn(arrayMap(fns, wrapAsync), function (fn, cb) { |
There was a problem hiding this comment.
fns can be a array|object|iterable
| var that = this; | ||
| return eachfn(fns, function (fn, cb) { | ||
| return eachfn(arrayMap(fns, wrapAsync), function (fn, cb) { | ||
| fn.apply(that, args.concat(cb)); |
There was a problem hiding this comment.
Do wrapAsync here instead
| var supported; | ||
| try { | ||
| /* eslint no-eval: 0 */ | ||
| supported = isAsync(eval('(async function () {})')); |
There was a problem hiding this comment.
Eval is evil. Why not Function?
supported = isAsync(new Function("return (async function () {})")());
There was a problem hiding this comment.
eval can be abused in the same way that new Function can be abused. I'd rather just use eval here
There was a problem hiding this comment.
new Function() and eval are equivalently evil. Here, they are necessary, because there is no other way to detect async support without causing a parse error that halts JS execution.
There was a problem hiding this comment.
I'm good with using eval here instead of new Function.
hargasinski
left a comment
There was a problem hiding this comment.
I'm really excited for this, awesome work! 😄
| * ], callback); | ||
| * | ||
| * // es6 example | ||
| * // es2017 example |
There was a problem hiding this comment.
Would it be useful to add a note here that async functions are supported out of the box (when not transpiled)?
There was a problem hiding this comment.
Yeah, we should clarify here.
| @@ -19,7 +20,7 @@ import onlyOnce from './internal/onlyOnce'; | |||
| * passes. The function is passed a `callback(err)`, which must be called once | |||
| * it has completed with an optional `err` argument. Invoked with (callback). | |||
| * @param {Function} test - synchronous truth test to perform after each | |||
There was a problem hiding this comment.
👍 for using typedef for this. Does this mean most of the docs should to be updated to reflect that iteratee should be an AsyncFunction type?
| var supported; | ||
| try { | ||
| /* eslint no-eval: 0 */ | ||
| supported = isAsync(eval('(async function () {})')); |
There was a problem hiding this comment.
I'm good with using eval here instead of new Function.
| * This type of function is also referred to as a "Node-style async function". | ||
| * | ||
| * Wherever we accept a Node-style async function, we also directly accept an | ||
| * ES2017 `async` function. |
There was a problem hiding this comment.
| * ES2017 `async` function. | ||
| * In this case, the `async` function will not be passed a callback, and any | ||
| * thrown error will be used as the `err` argument of a theoretical callback, | ||
| * and the return value will be used as the `result` value. |
There was a problem hiding this comment.
What do you mean the async function will not be passed a callback? Do you mean the result of the async function?
| * thrown error will be used as the `err` argument of a theoretical callback, | ||
| * and the return value will be used as the `result` value. | ||
| * | ||
| * Note that we can only detect native `async function`s in this case. |
There was a problem hiding this comment.
Note, due to JavaScript limitations, we can only detect native
async functions and not polyfilled implementations.
|
@megawac @hargasinski Many doc updates for your 👀. 😓 |
| }, | ||
| "parserOptions": { | ||
| "ecmaVersion": 6, | ||
| "ecmaVersion": 8, |
There was a problem hiding this comment.
what is es8? can we set this to 2017/2018 whatever?
There was a problem hiding this comment.
ES8 is eslint's shorthand for ES2017. No, you can't use "2017"... Just subtract 2009. 😛
| "babel-plugin-istanbul": "^2.0.1", | ||
| "babel-plugin-transform-es2015-modules-commonjs": "^6.3.16", | ||
| "babel-preset-es2015": "^6.3.13", | ||
| "babel-preset-es2017": "^6.22.0", |
There was a problem hiding this comment.
Yes, otherwise babel can't parse the test file where we use async functions, even if they're being used natively.
|
👏 awesome work, pretty excited for this |
|
I'm a little late, but really great work. I'm excited about this 💯 |
#1386
This adds support for passing
asyncfunctions wherever it might make sense.Obviously we are duplicating some core functionality with things like
mapandrace, but this allows us to treat things uniformly. We do have some good value to add with functions that limit concurrency, and adding more higher-order operations that justmapandeach(as you would get withPromise.map()andPromise.all()). "Lodash forasyncfunctions" is a good thing to strive to be.Most of the control flow functions are of dubious value, (
waterfall,parallel,whilst), but you can do some really neat things withautoandqueue. (I really love theautoInjectshorthand test!)The utility functions are a bit strange.
retry,reflect,memoizeandtimeoutnow take in anasyncfunction and return a callback-accepting function. It feels like those should create a Promise-returning function.