Comments (7)
take
is an operator, meaning that it takes a number max
and returns a function, which takes a callbag (the original source) and then returns a new function (a new callbag, this one will be the source in the sink's eyes).
The sink (like forEach) will subscribe to the takeSource
and the take operator will do its magic, meaning that it will subscribe to the original source and act as a proxy.
When the new callbag source returned by take
reaches the number max
of emitted items it sends a 2
to the sink but the sink will never send a 2
upwards to terminate it.
That's the meaning of it :-)
from here we can see:
const take = max => source => function takeSource(start, sink) {
if (start !== 0) return;
let taken = 0;
let sourceTalkback;
function talkback(t, d) {
if (taken < max) sourceTalkback(t, d);
}
source(0, (t, d) => {
if (t === 0) {
sourceTalkback = d;
sink(0, talkback);
} else if (t === 1) {
if (taken < max) {
taken++;
sink(t, d);
if (taken === max) {
sink(2);
sourceTalkback(2);
}
}
} else {
sink(t, d);
}
});
};
module.exports = take;
ex.:
pipe(
fromIter('abcdef'),
take(2),
forEach(console.log) . // a - b|
);
from callbag.
Why is it the case that the sink must not terminate the source? Here is a case where the implementation of callbag-take leads to a double termination
from callbag.
I agree with @RylinMirabel.
Maybe this situation rarely occurs in practice, but it is a bug; take
should only terminate the sink if it hasn't been teminated yet itself.
from callbag.
Ok using take(2) followed by another take(2) isn't something that I considered because it's not a realistic case
https://repl.it/repls/UntrueBisqueMice
adding a flag end: boolean
from callbag.
That still results in mutual termination between the two take callbags, although the downstream take callbag hides that from its sink. See the last two lines printed by the logger in this repl. To prevent mutual termination (which can lead to out-of-spec behaviour if unlike take, the downstream callbag does not disconnect its source from its sink upon termination), we need to check the end flag before sending any end signal (to either the source or the sink), and we need to set the end flag upon receiving any end signal. See this repl for a possible fix.
from callbag.
it's not a realistic case
It can occur due to some composition.
from callbag.
I followed this thread and had my own thoughts, but you all figured it out, and I agree it's a bug in callbag-take, for which a PR has solved. The spec is quite clear that termination shouldn't be mutual, so I don't think we need this issue open. :)
from callbag.
Related Issues (20)
- Use named constants and non-zero power of two values for type parameter HOT 1
- Versioning HOT 1
- I'm missing something HOT 12
- Calling a sourceTalkback with 1 and data HOT 1
- How to handle additional websocket connection state HOT 1
- Consuming pullable sources needs careful handling to avoid stack overflow HOT 21
- More readable implementation of callback based duplex stream HOT 13
- Errors and Termination HOT 11
- Ability to discover what IDs a callbag supports HOT 8
- A more concise way HOT 6
- Are asynchronous handshakes permitted? HOT 1
- What if an exception is thrown during callbag execution? HOT 19
- sink termination propagation
- Control flow assumptions HOT 16
- Express variance in types HOT 12
- Ability to detect callbags
- Stricter types? HOT 1
- Missing index.js referenced from "main" in package.json breaks Vite HOT 1
- Why do we say sink is a callbag?
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 callbag.