The basic of stream in Dart
Going through the fundamentals of stream api in dart programming language.
Filter by Category
Filter by Author
Going through the fundamentals of stream api in dart programming language.
Posted by Baraa Abuzaid
Tutorial on how to implement the proxy design pattern with Kotlin
Posted by Baraa Abuzaid
Tutorial on composite design pattern with code example In Kotlin
Posted by Baraa Abuzaid
Here we'll implement a draggable map with a fixed marker on top. that's only change when moving the map just like UBER.
Posted by Baraa Abuzaid
Get up and running with Kotlin in no time
Posted by Baraa Abuzaid
Discussing Kotlin Interface delegation and the shortcoming of the implementation inheritance
Posted by Baraa Abuzaid
The adapter design pattern is a structural design pattern that's very useful when maintaining a legacy code or adding a new features.
Posted by Baraa Abuzaid
The Façade design pattern is a structural design pattern. It reduces coupling and improves code readability.
Posted by Baraa Abuzaid
Will be going through the Creational Design Pattern illustrating how and where to use it.
Posted by Baraa Abuzaid
This tutorial will explain the fundamentals of ViewModel and LiveData and how to use them by creating simple demo App that shows recent movies.
Posted by Baraa Abuzaid
Going through the fundamentals of stream api in dart programming language.
If you’ve been toying around with Dart and Flutter you would’ve noticed how streams are very much well integrated into the systems. streams are a very powerful concept that paves the way into building very solid abstractions, that’ll probably let you reason about your problem domain elegantly.
So what streams in Dart? It is basically a sequence of asynchronous events that may or may not be ready at the time you asked for it But, rather tells you when it’s ready. In general, it is the Dart way on doing Async programming and if you are coming for java’s world it’s very similar to Java 8 streams API. Meanwhile, in Dart there is also another way of doing Async. Which is Future and it is also very much the same as promise in javascript. So if you’re Java/Js developer switching to Dart will feel very much at home.
In the beginning, it gets very easy to confuse between the two (stream/future). but, there are settle differences between them. In this article will discuss the stream in Dart and leave (Dart Future) to the subsequent one. So to make it clear let’s look at a simple example. Suppose we would like to compute the average for a list of integers. Doing so by using stream will be like.
main() async{
List<int> set1 = [10,12,13,30];
Stream<int> streamOfNumbers = computeSum(set1);
int result=0;
await for(int value in streamOfNumbers){
result +=value;
}
print(result);// result : 65
}
Stream<int> computeSum(List<int> lst) async*{
for(int x in lst){
yield x;
}
}
Here you may notice that we are looping through a list of values with normal for-loop syntax but instead of using return value we use yield. yield allow us to pass the result back to the stream as they are becoming available. Basically returning the result in chunks.
In addition, the function must be declared as an asynchronous generator with the help of (async*) modifier.
Moreover, in the main function to process the stream, we are waiting for it as it becomes available, using (await for-loop). Furthermore, (await for-loop) consumes the stream allowing us to loop through its values as if it is a normal list. But there is gotcha here…
when you are using await to consume a stream or any async operations we must also declare the function as an asynchronous function by using the (async) modifiers. As we are already done in the main function. And that’ll lead us to our next point.
The generator is a function the return a sequence. if it is asynchronous we use async* otherwise sync*. However, in both cases, the return value from the generator is evaluated lazily. using what’s called lazy evaluation. In other words, the evaluation of the sequence will differ until it’s been consumed. In the case of the asynchronous generator. The generator will be responsible for pushing the value to the consumer on its own pace.
The following table might help you to remember the different types that we discuss so far.
[eckosc_column_container count=”four”]
[eckosc_column_item]Type[/eckosc_column_item]
[eckosc_column_item][/eckosc_column_item]
[eckosc_column_item]Modifier[/eckosc_column_item]
[eckosc_column_item]Return Type[/eckosc_column_item]
[/eckosc_column_container]
[eckosc_column_container count=”four”]
[eckosc_column_item]synchronous function[/eckosc_column_item]
[eckosc_column_item][/eckosc_column_item]
[eckosc_column_item]none[/eckosc_column_item]
[eckosc_column_item]any[/eckosc_column_item]
[/eckosc_column_container]
[eckosc_column_container count=”four”]
[eckosc_column_item]asynchronous function[/eckosc_column_item]
[eckosc_column_item][/eckosc_column_item]
[eckosc_column_item]async[/eckosc_column_item]
[eckosc_column_item]Futur[/eckosc_column_item]
[/eckosc_column_container]
[eckosc_column_container count=”four”]
[eckosc_column_item]synchronous generator function[/eckosc_column_item]
[eckosc_column_item][/eckosc_column_item]
[eckosc_column_item]sync*[/eckosc_column_item]
[eckosc_column_item]Iterable[/eckosc_column_item]
[/eckosc_column_container]
[eckosc_column_container count=”four”]
[eckosc_column_item]asynchronous generator function[/eckosc_column_item]
[eckosc_column_item][/eckosc_column_item]
[eckosc_column_item]async*[/eckosc_column_item]
[eckosc_column_item]Stream[/eckosc_column_item]
[/eckosc_column_container]
Now, let’s do the same things by throwing some functional programming into the mix
main(){
List<int> set1 = [10,12,13,30];
computeSum(set1)
.reduce((accumlator,value)=> accumlator += value)
.asStream().forEach(print); // result : 65
}
Stream<int> computeSum(List<num> lst) async*{
for(num x in lst){
yield x;
}
}
Basically, we are doing the same thing, but instead of using for-loop, here we are using reduce() which is a functional programming feature that made available to us when using Dart streams. reduce()
execute a callback on each item on the stream with two params accumulator
and value
. The former has a hold of our previous return value and the latter has the current value in the stream. And because reduce consume our original stream, we need to push each return value from our reduce()
function into a new stream using asStream()
and pass it again to another function that is forEach()
to print out the result.
Photo by Alexandra Cozmei
One of the things that you may dislike about react native is this kind of mysterious errors that popup from time to time. Where anything works in harmony and suddenly you...
your introduction of the article explaining the concept is good. Also, streams can be paused which is a powerful feature. You can pause and resume whenever you feel like without interrupting or breaking the code.
I don’t understand about `asStream()` method yet, however `.asStream().forEach(print)` ca be replaced by `.then((value) => print(value))`; it does make more sense for me.