Dart와 JavaScript는 많은 개념을 공유한다. Dart 역시 이벤트 루프에서 실행되고, 비동기 프로그래밍을 위한 Future라는 개념이 존재한다. Future는 자바스크립트의 Promise와 비슷하다. Dart는 정적 타입 언어이기 때문에 타입스크립트를 사용한 경험이 있다면 Dart를 더 쉽게 배울 수 있다.
Dart와 JavaScript의 다른 점과 비슷한 점을 Learning Dart as a JavaScript developer 페이지에 자세히 설명돼 있어서 정리해봤다.
<aside> <img src="/icons/search_gray.svg" alt="/icons/search_gray.svg" width="40px" /> 아래는 Part 1에서 이어지는 Part 2 내용
</aside>
자바스크립트와 마찬가지로 Dart 가상머신(VM)은 단일 이벤트 루프를 사용하여 코드를 실행한다. 모든 코드는 동기적으로 실행되지만, 비동기 도구를 통해 실행 순서를 제어할 수 있다.
자바스크립트에 Promise가 있다면 Dart엔 Future가 있다. 작동 방식 역시 비슷하다.
// JS
const httpResponseBody = func();
httpResponseBody.then((value) => {
console.log(`Promise resolved to a value: ${value}`);
});
// Dart
Future<String> httpResponseBody = func();
httpResponseBody.then((String value) {
print('Future resolved to a value: $value');
});
Futures는 프로미스처럼 실패할 수 있고 catchError
메서드를 통해 오류를 처리할 수 있다.
// JS
httpResponseBody
.then(...)
.catch(err => {
console.log(
"Promise encountered an error before resolving."
);
});
// Dart
httpResponseBody
.then(...)
.catchError((err) {
print(
'Future encountered an error before resolving.'
);
});
Promise.resolve()
처럼 즉시 완료되는 Future를 생성할 수도 있다.
String str = 'String Value';
Future<String> strFuture = Future<String>.value(str);
strFuture.then(print); // String Value
Dart도 Async/Await 구문을 지원하며 자바스크립트처럼 async
키워드를 사용한 함수는 Future를 반환한다.
예를들어 String을 반환하는 함수에 async
를 추가했다면 Future<String>
을 반환한다.
// JavaScript
// Promise<string> 반환
async function fetchString() {
return "String Value";
}
fetchString().then((str) => {
console.log(str); // String Value
});
// Dart
// Future<string> 반환
Future<String> fetchString() async {
return 'String Value';
}
fetchString().then((String str) {
print(str); // String Value
});
then()
대신 await
키워드를 이용해서 Future 값을 얻을 수 있다. 자바스크립트와 마찬가지로 await
키워드는 async
함수 내에서만 사용할 수 있다.
// await는 async 컨텍스트에서만 사용할 수 있다.
Future<void> asyncFunction() async {
var str = await fetchString();
print(str); // 'String Value'
}
스트림이 값을 전송할 때마다 해당 스트림의 listen
메서드가 호출된다.
Stream<int> stream = ...
stream.listen((int value) {
print('A value has been emitted: $value');
});
listen
메서드는 오류 처리 혹은 완료를 위한 선택적 콜백을 포함한다.
stream.listen(
// onData: 스트림이 새로운 데이터를 전송할 때 호출
(int value) { ... },
// onError: 스트림에서 오류가 발생했을 때 호출
onError: (err) {
print('Stream encountered an error! $err');
},
// onDone: 스트림이 완료됐을 때 호출
onDone: () {
print('Stream completed!');
},
);
listen
메서드는 StreamSubscription
인스턴스를 반환하고, 이 인스턴스를 통해 스트림 수신을 중지할 수 있다.
StreamSubscription subscription = stream.listen(...);
subscription.cancel();