Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
7 views

Week 3 - Asynchronous Programming and Iterables

flutter

Uploaded by

amnaahmad2072003
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

Week 3 - Asynchronous Programming and Iterables

flutter

Uploaded by

amnaahmad2072003
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 34

EC303 – MOBILE APPLICATION DEVELOPMENT

FOR SMES
WEEK 3
OBJECTIVES

 Asynchronous Programming
 Iterable collection
ASYNCHRONOUS PROGRAMMING
WHY ASYNCHRONOUS CODE MATTERS

 Asynchronous operations let your program complete work while waiting for another
operation to finish. There are some common asynchronous operations which are :
• Fetching data over a network.
• Writing to a database.
• Reading data from a file.
WHY ASYNCHRONOUS CODE MATTERS

 Such asynchronous computations usually provide their result


 as a Future
 or, if the result has multiple parts, as a Stream.

 These computations introduce asynchrony into a program.


 To accommodate that initial asynchrony, other plain Dart functions also need to become
asynchronous.
 To interact with these asynchronous results, you can use the async and await keywords.
KEY TERMS

• Synchronous operation: A synchronous operation blocks other operations from


executing until it completes.
• Synchronous function: A synchronous function only performs synchronous operations.
• Asynchronous operation: Once initiated, an asynchronous operation allows other
operations to execute before it completes.
• Asynchronous function: An asynchronous function performs at least one asynchronous
operation and can also perform synchronous operations.
WHAT IS A FUTURE?

 A future (lower case "f") is an instance of the Future (capitalized "F") class.
 A future represents the result of an asynchronous operation and can have two states:
 Uncompleted
 Uncompleted is a Dart term referring to the state of a future before it has produced a value.

 Completed
 If the asynchronous operation succeeds, the future completes with a value. Otherwise, it completes with an
error.
COMPLETED

Completing with a value


 A future of type Future<T> completes with a value of type T.
 For example, a future with type Future<String> produces a string value.
 If a future doesn't produce a usable value, then the future's type is Future<void>.

Completing with an error


 If the asynchronous operation performed by the function fails for any reason, the future
completes with an error.
EXAMPLE – SYNCHRONOUS PROGRAMMING

String getName() => "Thunderbird";


void main(List<String> args) {
print(getName());
}

Output
Thunderbird
FUTURE

 Functions can return a Future


 Means results will be available in the future
 http.get(url)  HTTP GET request
 returns a Future that resolves to an http.Response object

 Some RESTFul API are synchronous, i.e they block


 Future move from Uncompleted Completed
 Can take time
WORKING WITH FUTURE

 The async and await keywords provide a declarative way to define asynchronous
functions and use their results.
 Remember these two basic guidelines when using async and await:
 To define an async function, add async before the function body:
 The await keyword works only in async functions.

 Here's an example that converts main() from a synchronous to asynchronous function.


 First, add the async keyword before the function body:

void main() async { ··· }


WORKING WITH FUTURE

 If the function has a declared return type, then update the type to be Future<T>, where T
is the type of the value that the function returns. If the function doesn't explicitly return a
value, then the return type is Future<void>:

Future<void> main() async { ··· }


 Now that you have an async function, you can use the await keyword to wait for a future to
complete:

print(await createOrderMessage());
EXAMPLE

Future<String> getName() async => "Thunderbird";


void main(List<String> args) {
print(getName().runtimeType);
}
EXAMPLE

Future<String> getName() async {


sleep(Duration(seconds: 3));
return "Thunderbird";
}

void main(List<String> args) {


print(getName());
}
EXAMPLE

Future<String> getName() async {


sleep(Duration(seconds: 3));
return "Thunderbird";
}

void main(List<String> args) async {


print(await getName());
}
EXAMPLE

Future<void> doSomethingAsync() async {


print('Starting...');
await Future.delayed(Duration(seconds: 1));
print('END of function!');
}

void main() {
print('Before calling doSomethingAsync');
doSomethingAsync();
print('Main');
}
THEN KEYWORD

 Basic Syntax

futureObject.then((result) {
// do something with the result of the future
}).catchError((error) {
// handle any errors that occur while processing the future
});
EXAMPLE

Future<int> addNumbers(int a, int b) {


return Future.delayed(Duration(seconds: 1), () => a + b);
}

void main() {
addNumbers(2, 3).then((result) {
print('The result is: $result');
}).catchError((error) {
print('An error occurred: $error');
});
}
EXAMPLE

Future<int> addNumbers(int a, int b) {


return Future.delayed(Duration(seconds: 1), () => a + b);
}

void main() {
addNumbers(2, 3).then((result) {
print('The result is: $result');
}).catchError((error) {
print('An error occurred: $error');
});
print("Hello");
}
TASK – PREDICT THE OUTPUT OF BOTH
String createOrderMessage() { Example: asynchronous functions #
var order = fetchUserOrder(); Future<String> createOrderMessage() async {

return 'Your order is: $order'; var order = await fetchUserOrder();

} return 'Your order is: $order';


}

Future<String> fetchUserOrder() =>


Future<String> fetchUserOrder() =>
// Imagine that this function is more
complex and slower. // Imagine that this function is more complex and
slower.
Future.delayed(
Future.delayed(
const Duration(seconds: 2),
const Duration(seconds: 2),
() => 'Large Latte',
() => 'Large Latte',
); );

void main() { Future<void> main() async {


print('Fetching user order...'); print('Fetching user order...');
print(createOrderMessage()); print(await createOrderMessage());
} }
ITERABLES COLLECTIONS IN DART
OVERVIEW

• Understand the power of Iterable collections in Dart.


• Learn how to efficiently work with Lists and Sets.
• Explore various methods and operations available for manipulation.
WHAT ARE COLLECTIONS?

 A collection is an object that represents a group of objects, which are called elements.
 Iterables are a kind of collection.
 A collection can be empty, or it can contain many elements.
 Depending on the purpose, collections can have different structures and implementations.
 These are some of the most common collection types:
 List: Used to read elements by their indexes.
 Set: Used to contain elements that can occur only once.
 Map: Used to read elements using a key.
WHAT IS AN ITERABLE?

 An Iterable is a collection of elements that can be accessed sequentially.


 In Dart, an Iterable is an abstract class, meaning that you can't instantiate it directly.
However, you can create a new Iterable by creating a new List or Set.
 Both List and Set are Iterable, so they have the same methods and properties as the
Iterable class.
 A Map uses a different data structure internally, depending on its implementation.
 For example, HashMap uses a hash table in which the elements (also called values) are obtained
using a key.
 Elements of a Map can also be read as Iterable objects by using the map's entries or values
property.
EXAMPLE

 This example shows a List of int, which is also an Iterable of int:

Iterable<int> iterable = [1, 2, 3];


 The difference with a List is that with the Iterable, you can't guarantee that reading
elements by index will be efficient. Iterable, as opposed to List, doesn't have the []
operator.
 For example, consider the following code, which is invalid:

Iterable<int> iterable = [1, 2, 3];


int value = iterable[1];
.ELEMENTAT()

 If you read elements with [], the compiler tells you that the operator '[]' isn't defined for
the class Iterable, which means that you can't use [index] in this case.
 You can instead read elements with elementAt(), which steps through the elements of the
iterable until it reaches that position.
Iterable<int> iterable = [1, 2, 3];
int value = iterable.elementAt(1);
READING ELEMENTS

 Sequentially access elements using for-in loop.

void main() {
const iterable = ['Salad', 'Popcorn', 'Toast'];
for (final element in iterable) {
print(element);
}
}
ACCESSING ELEMENTS

void main() {
 In some cases, you want to access only Iterable<String> iterable = const
the first or the last element of an ['Salad', 'Popcorn', 'Toast'];
print('The first element is $
Iterable.
{iterable.first}');
 With the Iterable class, you can't access print('The last element is $
the elements directly, so you can't call {iterable.last}');
iterable[0] to access the first element. }
Instead, you can use first, which gets the
first element.
 Also, with the Iterable class, you can't
use the operator [] to access the last
element, but you can use the last
property.
FINDING ELEMENTS

 Use firstWhere to find the first element that satisfies a condition.


CHECKING CONDITIONS

void main() {
const items = ['Salad', 'Popcorn', 'Toast'];
 The Iterable class provides
two methods that you can if (items.any((item) => item.contains('a'))) {
use to verify conditions: print('At least one item contains "a"');
 any(): Returns true if at least }
one element satisfies the
condition. if (items.every((item) => item.length >= 5)) {
 every(): Returns true if all print('All items have length >= 5');
elements satisfy the }
condition. }
FILTERING ELEMENTS

 Use where() to find elements meeting specific criteria.

var evenNumbers = numbers.where((number) => number.isEven);


for (final number in evenNumbers) {
print('$number is even');
}
MAPPING ELEMENTS

 Mapping Iterables with the method map() enables you to apply a function over each of the
elements, replacing each element with a new one.
Iterable<int> output = numbers.map((number) => number * 10);
 In this example, each element of the Iterable numbers is multiplied by 10.
 You can also use map() to transform an element into a different object—for example, to
convert all int to String, as you can see in the following example:
Iterable<String> output = numbers.map((number) => number.toString());
ANY QUESTIONS?

You might also like