임의의 순서로 또는 동시에 작업이 실행될 수 있다.
비동기를 처리하는 방법에는 콜백, Future, async - await 방식이 있다.
코드가 순서대로 실행된다.
작업이 완료될 때까지 프로그램이 중단될 수 없다.
모든 작업은 이전 작업의 실행이 완료될 때까지 기다려야 한다.
콜백은 실행 가능한 함수를 인자로 전달하여, 특정 상황이 발생할 때 호출되게 하는 방식이다.
현실 세계에서 콜백의 예시 :
음식을 주문하고 진동벨을 가지고 기다리면 음식이 준비되면 손님을 호출(Callback)하는 상황
회원가입의 3단계
final List database = [];
void main(List<String> arguments) {
final result = register({
'email': 'abc@abc.com',
'password': '123456',
'name': 'John Doe',
});
print(result.call());
print(database);
}
Function register(user) {
return saveDb(user, (user) {
return sendEmail(user, (user) {
return getResult(user);
});
});
}
Function saveDb(user, callback) {
print('saving $user to db');
return callback(user);
}
Function sendEmail(user, callback) {
print('sending email to $user');
database.add(user);
return callback(user);
}
Function getResult(user) {
return () => 'success register $user';
}
실행 결과
saving {email: abc.com, password: 123456, name: John Doe} to db
sending email to {email: abc.com, password: 123456, name: John Doe}
success register {email: abc.com, password: 123456, name: John Doe}
[{email: abc.com, password: 123456, name: John Doe}]
비동기 처리 로직을 위해 콜백 함수를 연속해서 사용할 때 발생하는 문제.
미래에 완료되는 객체
Javascript 의 Promise 에 대응
Future 는 ‘미래'에 받아올 값을 의미
Future<String> name;
Future<int> number;
Future<Person> person;
Dart 및 Flutter 의 많은 API 는 Future 타입을 리턴한다.
다음 코드는 비동기 코드를 시뮬레이트하기 위해 5 초 후에 실행되는 Future 함수를 정의한 것이다.
var delay = Future.delayed(Duration(seconds:5));
//2초 미래에 동작하는 코드 작성 예
void myFunction() {
print('start');
Future.delayed(Duration(seconds: 2), () {
print('2 seconds');
}); // Future.delayed
print('end');
}
Future 함수는 함수 본문 앞에 async
키워드를 지정해 줘야 한다.
대기하고 싶은 비동기 함수를 실행할 때 await
키워드를 사용해주면 코드를 작성한 순서대로 실행된다.
//회원가입 3단계 함수들을 Future 타입을 변경
Future<void> saveDb(user) async{
print('saving $user to db');
}
Future<void> sendEmail(user) async{
await Future.delayed(Duration(seconds: 2));
print('sending email to $user');
database.add(user);
}
Future<void> getResult(user) async{
return 'success register $user';
}
Future 함수는 결과를 then() 함수를 통해서 받을 수 있다.
then() 함수로 전달되는 콜백 함수에 다음에 실행할 코드를 작성하면 된다.
다음 코드가 Future라면 계속해서 then() 을 이어서 결과를 전달받을 수 있다.
불필요한 인자는 _ 를 쓰는 것이 관례이다.
//회원가입 3단계 함수들을 Future 타입을 변경
final user = {
'email' : 'abc@abc.com'
'password' : '123456'
'name' : 'John Doe'
};
saveDb(user)
.then((_) => sendEmail(user))
.then((_) => getResult(user))
.then((value) => print(user));
Future 는 성공(then)일 수도 있고 오류(catchError)일 수도 있다.
delay
.then((value) => print('I have been waiting'))
.catchError((err) => print(err));
catchError() 함수를 사용하면 에러 처리를 할 수 있다
에러를 발생시킬 때는 Future.error() 를 사용한다.
throw Exception() 으로 예외를 발생시킬 수 있다.
async - await 는 비동기 코드를 작성할 때 더 깔끔한 코드를 제공한다.
await 키워드는 해당 Future 가 끝날 때까지 함수 실행을 기다린다.
Future<String> runInTheFuture() async {
var data = await Future.value('world');
return 'hello $data';
}
//async - await 를 사용한 이메일 보내기 3단계
//등록 과정을 깔끔하게 작성했다.
Future<String> register(user) async {
await saveDb(user);
await sendEmail(user);
return await getResult(user);
}
//main() 함수도 async 를 붙이면 await를 사용할 수 있다.
void main(List<String> arguments) async {
final user = {
'email' : 'abc@abc.com'
'password' : '123456'
'name' : 'John Doe'
};
final result = await register(user);
print(result);
}
병렬 처리는 동시에 여러가지 일을 진행하는 것이다.
Future 함수는 await 없이 사용하면 동시에 여러개를 실행할 수 있다.