본문 바로가기
개발/dart

7. Use Future-Based APIs

by 허허 그림 2014. 3. 2.
728x90

* 전체 링크

1.get started

2. Connect Dart & HTML

3. Add Elements to the DOM

4, Remove DOM Elements

- 5. Install Shared Packages

6. Define a Custom Element

7. Use Future-Based APIS

8. Use Streams for Data

9. Fetch Data Dynamically

10. Get Input from a Form

11. Use Indexed DB

12. Write Command-line Apps


Use Future-Based APIs
Future 기반 API 사용하기

Use Futures for asynchronous operations.
비동기 작동 기능 사용하기.

Written by Shailen Tuli

Dart is a single-threaded programming language. If any code blocks the thread of execution (for example, by waiting for a time-consuming operation or blocking on I/O) the program effectively freezes. Asynchronous operations let your program run without getting blocked. Dart uses a Future object to perform asynchronous operations.

Dart는 싱글 쓰레드 프로그래밍 언어입니다. 어떤 코드가 실행 쓰레드(예를 들어, 시간이 오래 걸리는 작업이나 I/O 블락킹에 의한 기다림)를 블락시킨다면, 효과적으로 그 프로그램을 중시시킵니다. 비동기 작동은 프로그램이 블락이 되는 일이 없이 실행이 됩니다. Dart 는 비동기 작동을 위해서 Future 객체를 사용합니다.

Introduction
소개

Let’s look at some code that could possibly cause a program to freeze:

프로그램이 뻗어버리는 문제를 야기할 수 있는 아래의 코드를 보자.

import 'dart:io';

void printDailyNewsDigest() {
 File file
= new File("dailyNewsDigest.txt");
 print
(file.readAsStringSync());
}

void main() {
 printDailyNewsDigest
();
 printWinningLotteryNumbers
();
 printWeatherForecast
();
 printBaseballScore
();
}

Our program reads the news of the day from a file, dailyNewsDigest.txt, prints it, and then prints a bunch of other items of interest to the user:

프로그램은 오늘의 뉴스를 dailyNewsDigest.txt파일로 읽고 출력하고 그 다음에 사용자가 관심있어할만한 다른 주제들을 출력합니다.

<Contents of dailyNewsDigest.txt>
Winning lotto numbers: [23, 63, 87, 26, 2]
Tomorrow's forecast: 70F, sunny.
Baseball score: Red Sox 10, Yankees 0

Our code is problematic: since readAsStringSync() blocks, the remaining code runs only when readAsStringSync() returns with the contents of the file, however long that takes. And if reading the file takes a long time, the user waits passively, wondering if she won the lottery, what tomorrow’s weather will be like, and who won today’s game. Not good.

이 코드는 문제가 많습니다. readAsStringSync() 블락 이후에, 남아 있는 코드는 readAsStringSync()는 그 파일의 내용을 리턴을 하고 난 후에  실행합니다. 그러나 그 작업은 오래 걸립니다. 그리고 파일 읽는 작업이 오래 걸린다면, 사용자는 그녀가 로또를 땄는지, 내일 날씨가 어떻는지, 그리고 누가 오늘의 게임에 이겼는지를 궁금해 하면서 기다리기만 합니다. 이건 좋지 않군요.

To help keep the application responsive, Dart library authors use an asynchronous model when defining functions that do potentially expensive work. Such functions return their value using a Future

즉각 반응하는 어플리케이션을 만들기 위해, Dart 라이브러리 제작자는 잠재적으로 비용이 많이 드는 작업을 처리하기 위해 비동기 모델을 사용합니다. 이런 기능은 Future 를 사용해서 값을 리턴합니다.

What is a Future?
Future는?

A Future represents a means for getting a value sometime in the future. When a function that returns a Future is invoked, two things happen:

Future는 미래에 언제가는 값을 가져오기 위한 수단을 나타냅니다. Future 를 리턴하는 함수가 호출될때 , 두가지 일이 일어납니다.

  1. The function queues up work to be done and returns an uncompleted Future object immediately.
    이 함수는 해야할 작업을 대기열에 넣고 즉시 완전히 끝나지 않은 Future 객체를 반환합니다.

  2. Later, when a value is available, the Future object completes with that value (or with an error; we’ll discuss that later).
    그 후에, 값이 사용가능해질때, 그 Future 객체는 그 값(또는 에러, 이것에 대해서는 나중에 보겠습니다)을 가지고 작업을 완료 합니다.

To get the value that the Future represents, use the then() method to register a callback. This callback fires when the Future completes.

Future 가 나타내는 값을 얻기 위해, 콜백를 등록하는 then() 메소드를 사용하세요. 이 콜백은 Future 가 완료될때 실행됩니다.

Using a Future
Future 사용하기.

Let’s rewrite printDailyNewsDigest() to get the file contents asynchronously:

비동기적으로 파일 내용을 가져오기 위해서 printDailyNewsDigest()을 재작성합니다.

import 'dart:io';
import 'dart:async';

void printDailyNewsDigest() {
 File file
= new File("dailyNewsDigest.txt");
 Future future
= file.readAsString();
 future
.then((content) {
   print
(content);
 
});
}

The printDailyNewsDigest() function now uses readAsString(), which is non-blocking. Calling readAsString() queues up the work to be done but doesn’t stop the rest of the code from executing. The program prints the lottery numbers, the forecast, and the baseball score; when readAsString() finishes reading the news file, the program prints its contents. If readAsString()takes a little while to complete its work, no great harm is done: the user gets to read other things before the daily news digest is printed.

printDailyNewsDiget() 함수는 지금 readAsString() 를 사용합니다. 이것은 non-blocking 함수입니다.readAsString() 호출은 해야할 작업(끝마쳐야 할 작업)을 대기열에 넣는 것이지만 실행에서 코드의 나머지 부분을 정지하는 것은 아닙니다. 이 프로그램은 로또 번호, 일기예보와 야구 점수를 출력합니다. readAsString() 함수가 뉴스 파일을 끝까지 다 읽었을때, 이 프로그램은 뉴스 파일의 내용을 출력합니다. readAsString() 가 파일을 완전히 읽는데 시간이 쫌 걸린다고 하더라도, 그것은 큰 피해가 아닙니다. 데일리 뉴스 다이제스트가 출력되기 전에 사용자는 다른 일을 할 수 있습니다.

Winning lotto numbers: [23, 63, 87, 26, 2]
Tomorrow's forecast: 70F, sunny.
Baseball score: Red Sox 10, Yankees 0
<Contents of dailyNewsDigest.txt>

Sequence of events during code execution
코드 실행중에 이벤트 순서

The preceding code executes in three steps:

앞선 코드는 다음의 3개 스텝으로 실행됩니다.

  1. The program enters main(), which calls printDailyNewsDigest(), which queues up the file reading task. After calling the remaining print functions, main() exits, but the program continues.
    이 프로그램은  
    printDailyNewsDigest() 함수를 호출하는 main() 함수로 들어갑니다.  printDailyNewsDigest() 함수는 파일 읽는 작업을 대기열에 넣습니다. 나머지 출력 함수를 호출한 후에,  main() 함수는 종료됩니다.그러나 프로그램은 계속 됩니다.

  2. The work scheduled by readAsString() is performed, and the contents of the file are read into memory. When the entire file is read, the Future completes with the file contents.
    readAsString()에 의해 스케줄되어진 작업은 수행되고, 파일의 내용이 메모리에 읽혀집니다. 전체 파일이 완전히 읽혀졌을때, Future은 파일의 내용 읽기를 완료합니다.

  3. The callback registered within then() fires and prints the contents of the news file.
    then()안에 등록된 콜백이 실행이 되고 뉴스 파일의 내용을 출력합니다.

Calling then() returns a new Future, which completes with the value returned by then()’s callback. This means that calls to then() can be chained (we’ll see examples of this later).

then() 호출은 새로운 Future 객체를 리턴합니다. 그 리턴되는 Future 객체는 then()의 콜백에 의해 리턴된 값으로 완료됩니다. 이것은 then() 을 호출하는 것이 연결되어 질 수 있다는 것을 의미합니다.( 이것은 나중에 예제를 보게 될 것 입니다.)

Handling errors when dealing with Futures
Future 를 다룰때 에러 처리하기.

If a Future-returning function completes with an error, the Future returned by then() also completes with an error. We can capture that error using catchError():

Future 반환 함수가 만약에 error로 완료가 된다면,  then()에 의해 반환된 이 Future 또한 error로 완료가 됩니다. catchError() 를 사용해서 error를 잡을 수 있습니다.

void printDailyNewsDigest() {
 File file
= new File("dailyNewsDigest.txt");
 Future future
= file.readAsString();
 future
.then((content) => doSomethingWith(content))
       
.catchError((e) => handleError(e));
}

If dailyNewsDigest.txt doesn’t exist or isn’t available for reading, the code above executes as follows:

dailyNewsDigest.txt 파일이 존재하지 않거나 읽기 불가능한 파일일 경우에, 위의 코드는 다음과 같이 실행됩니다.

  1. readAsString()’s Future completes with an error.
    readAsString()의 Future는 error상태로 완료됩니다.

  2. then()’s Future completes with an error.
    then()의 Future는 error 상태로 완료 됩니다.

  3. catchError()’s callback handles the error, catchError()’s Future completes normally, and the error does not propagate.
    catchError()의 콜백 은 에러를 처리합니다. catchError()의 Future는 정상적으로 완료가 되고 그 에러는 더 이상 전파되지 않습니다.

Chaining catchError() to then() is a common pattern when working with functions that return Futures. Consider this pairing the asynchronous equivalent of try-catch blocks.

then()에서 catchError()로 연결되는 것은 Future 을 리턴하는 함수로 작업할때 쓰이는 공통적인 패턴입니다. try-catch 블락에 동등하게 쓰이는 이런 비동기  한 쌍을 고려하세요.

Like then(), catchError() returns a new Future that completes with the return value of its callback.

then() 처럼, catchError() 함수는 그것의 콜백함수의 리턴 값으로 완료되는 새로운 Future를 리턴합니다.

For more details and examples, read Futures and Error Handling.

좀 더 자세하고 많은 예제를 원하면, Futures and Error Handling을 읽어보세요.

Calling multiple functions that return Futures

Consider three functions, expensiveA(), expensiveB(), and expensiveC(), that return Futures. You can invoke them sequentially (one function starts when a previous one completes), or you can kick off all of them at the same time and do something once all the values return. The Future interface is fluid enough to deal with both use cases.

3개의 함수인 expensiveA(), expensiveB(), 와 expensiveC(),를 생각해보세요. 이것들은 Future 를 리턴합니다. 당신은 이 함수들을 순차적으로(하나의 함수가 완료가 된 후에 다음 함수가 시작하는) 실행시킬수 있고 또는 3개를 동시에 시작해서 한번에 리턴되는 모든 값을 가지고  작업을 할 수도 있습니다. 이 Future 인터페이스는 이 2가지 케이스를 처리하기에 충분히 유동적입니다.

Chaining function calls using then()

연결되는 함수는 then() 을 호출합니다.


When Future-returning functions need to run in order, use chained then() calls:

Future 반환 함수가 순서대로 실행해야 할 필요가 있을 경우 연결된 then() 함수 호출을 사용하세요.

expensiveA().then((aValue) => expensiveB())
           
.then((bValue) => expensiveC())
           
.then((cValue) => doSomethingWith(cValue));

Nested callbacks also work, but they’re harder to read and not as Dart-y.

중첩된 콜백 함수들은 작동은 하지만, 그것들은 읽기가 어렵고 다트 스럽지 않습니다.


Waiting on multiple Futures to complete using Future.wait()

Future.wait()을 사용을 완료하기 위해 다중 Future  기다리기.


If the order of execution of the functions is not important, you can use Future.wait() to handle multiple Future objects without having to explicitly chain function calls.

함수의 실행 순서가 중요하지 않을 경우, 당신은 명시적으로 함수 호출을 연결 짓지 않고 여러개의 Future 객체를 처리하기 위해서 Future.wait()을 사용할 수 있습니다.

The functions get triggered in quick succession; when all of them complete with a value,Future.wait() returns a new Future. This Future completes with a list containing the values produced by each function.

이 함수는 빠르게 이어서 작동 시킵니다.; 그것들 모두가 값으로 완료할때 Future.wait()는 새로운 Future를 리턴합니다. 이 Future는 각각의 함수가 만들어낸 값들을 가지고 있는 리스트를 가지고 완료합니다.

Future.wait([expensiveA(), expensiveB(), expensiveC()])
     
.then((List responses) => chooseBestResponse(responses))
     
.catchError((e) => handleError(e));

If any of the invoked functions completes with an error, the Future returned by Future.wait()also completes with an error. Use catchError() to handle the error.

어떤 실행된 함수라도 에러로 완료가 될수 있다면, 이 Future.wait()에 의해서 리턴된 이 Future 또한 error로 완료가 됩니다. 이 에러를 처리하기 위해서 catchError()을 사용하세요.

Other resources

Read the following documentation for more details on using Futures:

Future 사용에 대해서 좀 더 자세한 문서를 원한다면 아래를 읽어 보세요.

What next?

  • The next tutorial, Fetch Data Dynamically, uses a Future when doing an HTTP request.

  • 다음 튜토리얼에서는, 동적으로 데이터 가져오기, HTTP request를 사용할때 Future 사용하기 입니다.

  • The example featured in Use IndexedDB uses many Futures when interacting with the database.

  • indexedDB 사용에서 볼수 있는 예시들은 데이터베이스와 상호작용할때 많은 Future 를 사용합니다.


300x250

'개발 > dart' 카테고리의 다른 글

9. Fetch Data Dynamically  (0) 2014.03.04
8. Use Streams for Data  (0) 2014.03.02
6. Defined a Custom Element  (0) 2014.03.02
5. Install Shared Packages  (0) 2014.03.02
4. Remove DOM Elements  (0) 2014.03.02

댓글