-
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
Implement flatTap #651
base: master
Are you sure you want to change the base?
Implement flatTap #651
Changes from 7 commits
9b41102
2d8a712
7172f19
1a2fb23
d3ee895
768f6c2
18a7add
689c356
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2167,6 +2167,44 @@ addMethod('doto', function (f) { | |
Stream.prototype.tap = Stream.prototype.doto; | ||
_.tap = _.doto; | ||
|
||
/** | ||
* Applies a function, which must return a (possibly empty) highland stream, to each value from the source, and re-emits the | ||
* source value when the function return ends. | ||
* | ||
* @id flatTap | ||
* @section Transforms | ||
* @name Stream.flatTap(f) | ||
* @param {Function} f - the function to apply | ||
* @api public | ||
* | ||
* const httpLog = H(new Promnise(res => { | ||
* setTimeout(() => { | ||
* console.log('Log'); | ||
* res('Success') | ||
* }, 3000) | ||
* })) | ||
* | ||
* _([1, 2, 3]).flatTap(httpLog) // Will emit [1,2,3] | ||
*/ | ||
|
||
addMethod('flatTap', function (f) { | ||
return this.flatMap(function (x) { | ||
return f(x).consume(function (err, y, push, next) { | ||
if (err) { | ||
// next(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you should push the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay, this is an interesting one though, as it is a tap you could argue the error should be silenced? I think I do agree with you though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's definitely a lot of uses of Also, your fix isn't entirely correct. It pushes |
||
push(null, _.nil); | ||
} | ||
else if (y === _.nil) { | ||
push(null, x); | ||
push(null, _.nil); | ||
} | ||
else { | ||
next(); | ||
} | ||
}); | ||
}); | ||
}); | ||
|
||
/** | ||
* Limits number of values through the stream to a maximum of number of values | ||
* per window. Errors are not limited but allowed to pass through as soon as | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4909,6 +4909,102 @@ exports['tap - doto alias'] = function (test) { | |
test.done(); | ||
}; | ||
|
||
|
||
exports.flatTap = { | ||
'flatTap - noValueOnError': noValueOnErrorTest(_.flatTap(function (x) { return _(); })), | ||
'flatTap - returnsSameStream': returnsSameStreamTest(function (s) { | ||
return s.flatTap(function (x) { return _([2]); }); | ||
}, [1], [1]), | ||
'flatTap - On a empty stream': function (test) { | ||
test.expect(1); | ||
var s = _([]).flatTap(function (x) { | ||
return _([6]); | ||
}); | ||
|
||
s.pull(valueEquals(test, _.nil)); | ||
test.done(); | ||
}, | ||
'flatTap - Returns an Empty stream': function (test) { | ||
test.expect(1); | ||
var s = _([3]).flatTap(function (x) { | ||
return _([]); | ||
}); | ||
|
||
s.pull(valueEquals(test, 3)); | ||
test.done(); | ||
}, | ||
'flatTap - Emits an multiple values': function (test) { | ||
test.expect(1); | ||
var s = _([3]).flatTap(function (x) { | ||
return _([5, 6, 7, 8]); | ||
}); | ||
|
||
s.pull(valueEquals(test, 3)); | ||
test.done(); | ||
}, | ||
'flatTap - argument function throws': function (test) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add a similar test to this, but for the stream (i.e., the return value of the argument function) emitting an error instead. Something like this, _([1, 2, 3, 4]).flatTap((x) => _((push) => {
push(err);
push(null, _.nil);
})); |
||
test.expect(4); | ||
var err = new Error('error'); | ||
var s = _([1, 2, 3, 4]).flatTap(function (x) { | ||
if (x === 1) { throw err; } | ||
if (x === 2) { _(['hello']); } | ||
if (x === 3) { throw err; } | ||
return _(['world']); | ||
}); | ||
|
||
s.pull(errorEquals(test, 'error')); | ||
s.pull(valueEquals(test, 2)); | ||
s.pull(anyError(test)); | ||
s.pull(valueEquals(test, 4)); | ||
test.done(); | ||
}, | ||
'flatTap - ArrayStream': function (test) { | ||
var seen = []; | ||
var f = function (x) { | ||
return _(function (push, next) { | ||
setTimeout(function () { | ||
var y = x * 2; | ||
seen.push(y); | ||
push(null, y); | ||
push(null, _.nil); | ||
}, 10); | ||
}); | ||
}; | ||
_([1, 2, 3, 4]).flatTap(f).toArray(function (xs) { | ||
test.same(xs, [1, 2, 3, 4]); | ||
test.same(seen, [2, 4, 6, 8]); | ||
test.done(); | ||
}); | ||
}, | ||
'flatTap - GeneratorStream': function (test) { | ||
var seen = []; | ||
var f = function (x) { | ||
return _(function (push, next) { | ||
setTimeout(function () { | ||
var y = x * 2; | ||
seen.push(y); | ||
push(null, y); | ||
push(null, _.nil); | ||
}, 10); | ||
}); | ||
}; | ||
var s = _(function (push, next) { | ||
push(null, 1); | ||
setTimeout(function () { | ||
push(null, 2); | ||
push(null, 3); | ||
push(null, 4); | ||
push(null, _.nil); | ||
}, 10); | ||
}); | ||
s.flatTap(f).toArray(function (xs) { | ||
test.same(xs, [1, 2, 3, 4]); | ||
test.same(seen, [2, 4, 6, 8]); | ||
test.done(); | ||
}); | ||
} | ||
}; | ||
|
||
tomwhale marked this conversation as resolved.
Show resolved
Hide resolved
|
||
exports.flatMap = function (test) { | ||
var f = function (x) { | ||
return _(function (push, next) { | ||
|
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.
Use
_
instead ofH
for the Highland object.