-
Notifications
You must be signed in to change notification settings - Fork 147
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
wrapAsync #548
wrapAsync #548
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trying out the new code review feature. See my comments.
addToplevelMethod('wrapAsync', function (f) { | ||
var stream = this; | ||
return function () { | ||
var self = this; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need a self
here. Just pass this
to f.apply
directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
var stream = this; | ||
return function () { | ||
var self = this; | ||
var args = slice.call(arguments); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can save an allocation by passing arguments
to f.apply
directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool! I've always assumed that arguments
must be converted to a proper array before you can use it like this.
return function () { | ||
var self = this; | ||
var args = slice.call(arguments); | ||
return stream(f.apply(self, args)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically f.apply()
should not throw, but we should wrap it in a try-catch just in case.
Furthermore, stream
can throw an error if the result of f.apply(...)
is not an acceptable type. Since stream
is less restrictive than we are, we should also check that the result is a promise before passing it to stream. If it is not a promise, we should return a _.fromError
with an appropriate error.
We don't want the wrapped function to ever throw since it is supposed to be async.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I followed along on this part. Please take a look at my updates
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep. What you did was correct.
* @param {Function} f - the function that returns a promise | ||
* @api public | ||
* | ||
* var Promise = require('bluebird'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Promise.resolve
and Promise.reject
are standard functions, so I'd prefer not to mention a specific Promise library here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. Removed the bluebird reference.
@@ -7389,6 +7389,65 @@ exports['wrapCallback - default mapper discards all but first arg'] = function ( | |||
}); | |||
}; | |||
|
|||
exports.wrapAsync = function (test) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current tests are all over the place, but please use the nodeunit grouping feature:
exports.wrapAsync = {
'basic functionality': function (test) {
...
},
'context': function (test) {
...
},
...
};
This will group all of the wrapAsync
tests together and allow us to manually run all only the tests in the group. It'll also be useful when I go in and finally split up this giant file.
Also, please add a test.expect(numAsserts)
at the start of every test so that omitted assertions will fail the test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup. I just copied the wrapCallback tests. It's good to know that you can group them like this and pass in the expected number of assertions.
}; | ||
|
||
exports['wrapAsync - context'] = function (test) { | ||
var o = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this test verifies that the context is correctly passed. You need to use this
inside f
in some way. This is probably a copy-paste error since the wrapCallback
version checks the context with test.equal(this, o);
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are correct. This is fixed now too.
Also, I'm aware that I have not updated the changelog. I have some questions about that and am planning to do it after the rest of the work is compete. |
try { | ||
promise = f.apply(this, arguments); | ||
if (!_.isObject(promise) || !_.isFunction(promise.then)) { | ||
throw (new Error('Wrapped function did not return a promise')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From a code style standpoint, I don't like explicitly throwing exceptions from within a try-catch like this. It looks wrong at first glance. You should just return _.fromError(...)
here.
Just one minor point. Everything else looks good. |
@vqvu I removed the throw from the try block and added an extra test for that specific error. I'm ready to update the changelog but I'm not sure what version to put this under. Would it be a new version 2.11.0? |
It should be under 3.0.0. |
Add wrapAsync. A function that wraps a function that returns a promise, transforming it to a function which accepts the same arguments and returns a Highland Stream instead.
Addresses #517
@vqvu I didn't add any additional error handling because it looks like the constructor already handles promise errors in the same way as _.fromError (by creating an error stream with a single value). I've included that code for reference: