상세 컨텐츠

본문 제목

Dart - Asynchronous programming

Dart

by techbard 2024. 1. 21. 11:47

본문

반응형
// Asynchronous programming
//
// Dart is a single-threaded language.
// It means that Dart uses a single thread to
// execute the code.
// Dart’s single thread runs in what is known as an isolate.
//
// In practice, there’re many tasks that can run asynchronously.
// The order does not matter.
// For example, reading from a file, downloading an image
// from a remote server, and connecting to a database.
//
// To schedule tasks asynchronously, Dart uses an event loop.
//

/*
Summary

- Dart is a single-threaded language.
- Dart uses an event loop to schedule asynchronous tasks.
- Dart always executes synchronous code immediately. 
It only executes the tasks in the microtask queue 
once the synchronous tasks are empty. 
And it only executes the tasks in the event queue once 
both synchronous tasks and the microtask queue are empty.
*/

// Introduction to the Dart Future
//
// A future is an object that represents the result of an asynchronous operation.
// A future object will return a value at a later time.
//
// A future has two states: uncompleted and completed.
// When a future completes, it has two possibilities:
//
// - Completed with a value
// - Failed with an error
//
// Dart uses the Future<T> class for creating future objects.
// Because the Future<T> is a generic class, the value it returns can be any object.
//
// In practice, you often consume future objects instead of creating them.
//
// When a future completes, you can get the return value.
// There are two ways to get the value after the future completes:
//
// - Using a callback
// - Using async and await keywords

void main(List<String> args) {
  // he following example uses the Future.delayed() constructor
  // to create a future object that returns the number 2 after one second:
  var future = Future<int>.delayed(Duration(seconds: 1), () => 2);
}

// 결과
(1 seconds later...)

 

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

  var future = Future<int>.delayed(Duration(seconds: 1), () => 2);
  future.then((value) => print(value));

  print(3);
}

// 결과
1
3
2

 

// First, add the async keyword to the main() function to make it asynchronous.
// Since the main() function doesn’t explicitly return a value, its return type is Future<void>.
Future<void> main() async {
  print(1);

  // Second, add the await keyword in front of the future object.
  // Once Dart encounters the await keyword,
  // it sends all the code starting from that line to the event queue
  // and waits for the future to complete. That’s why you see the number 2 before 3.
  var value = await Future<int>.delayed(Duration(seconds: 1), () => 2);
  print(value);

  print(3);
}

// 결과
1
2
3

 

void main(List<String> args) {
  print('Program started');
  fetchUserOrder().then((order) => print('Order is ready: $order'));

  fetchUserOrder2()
      .then((order) => print('Order is ready: $order'))
      .catchError((error) => print(error))
      .whenComplete(() => print('Done'));
}

Future<String> fetchUserOrder() => Future.delayed(
      Duration(seconds: 2),
      () => 'Cappuccino',
    );

Future<String> fetchUserOrder2() =>
    Future.delayed(Duration(seconds: 3), () => throw Exception('Out of milk'));


/*
Async programming

Most applications need this:
- Fetching data from the network
- Writing to a database
- Reading data from file

Your apps need to be responsive while waiting for async operations
to complete
-> In Dart this is done with Futures, async & await
-> Stremas: asynchronous events delivered over time
  -> Often used in reactive applications 
  (Flutter & other declarative framework)
*/

// 결과
Program started
Order is ready: Cappuccino
Exception: Out of milk
Done

 

import 'package:http/http.dart' as http;
import 'dart:convert' as convert;

void main(List<String> args) async {
  final post = await fetchPost();
  print(post.title);
  print(post.userId);
}

Future<Post> fetchPost() async {
  var uri = Uri.https('jsonplaceholder.typicode.com', '/posts/2');
  final response = await http.get(uri);
  // print(response.body);

  Map<String, dynamic> data = convert.jsonDecode(response.body);
  return Post(data['title'], data['userId']);
}

class Post {
  String title;
  int userId;

  Post(this.title, this.userId);
}

// 결과
qui est esse
1

 

import 'dart:math';

void main(List<String> args) {
  print('Before the future');
  final delay = Duration(seconds: 3);
  final rnd = Random();

  final myFuture = Future<int>.delayed(delay, () => rnd.nextInt(10))
      .then((value) => print(value))
      .catchError((error) => print('Error: $error'))
      .whenComplete(() => print('Future is complete'));

  print('After the future');
}

/*
States for future

- Uncompleted
- Completed with a value
- Completed with an error

callback

is any executable code that is passed as an argument to other code;
that other code is expected to call back (execute) the argument
at a given time.
*/

// 결과
Before the future
After the future
3
Future is complete

 

void main(List<String> args) async {
  print('Before the future');
  final delay = Duration(seconds: 3);
  final value = await Future<int>.delayed(delay, () => 33);
  print('Value: $value');
  print('After the future');
}

// 결과
Before the future
Value: 33
After the future

 

import 'dart:io';

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

void goEatPizza() {
  order();
  getPizzaOrdered().then((value) {
    eatAndPay(value);
  });
  chatting();
}

void eatAndPay(String pizza) {
  Duration waitTime = Duration(seconds: 3);
  sleep(waitTime);
  print('Paid $pizza and on my way home');
}

void chatting() {
  print('Chatting...');
}

Future<String> getPizzaOrdered() async {
  Duration waitTime = Duration(seconds: 3);
  String pizza = 'No pizza yet';
  await Future.delayed(waitTime, () {
    pizza = 'Pepperoni';
    print('Pizza delivered successfully');
  });

  return pizza;
}

void order() {
  print('Done ordering pizza');
}

// 결과
Done ordering pizza
Chatting...
Pizza delivered successfully
Paid Pepperoni and on my way home
반응형

관련글 더보기

댓글 영역