비동기 API - Java SDK
Java SDK를 사용하면 동기 및 비동기의 두 가지 방법으로 네트워크 및 디스크 리소스에 액세스할 수 있습니다. 동기 요청은 성공 또는 실패를 반환할 때까지 실행을 차단하는 반면, 비동기 요청은 콜백을 할당하고 다음 코드 줄로 실행을 진행합니다. 요청이 반환되면 콜백이 실행되어 결과를 처리합니다. 콜백에서 요청이 성공적으로 실행되었는지 확인하고, 반환된 결과 또는 반환된 오류에 액세스할 수 있습니다.
비동기 호출
SDK의 비동기 API 요청은 접미사 "Async"로 끝납니다. 사용 중인 SDK 부분에 따라 비동기 요청이 작동할 수 있는 여러 가지 방법이 있습니다.
Realm.Callback
동기화 여부와 관계없이 영역 을 열기 위한 비동기 호출은 Realm.Callback 유형의 최종 매개변수를 사용합니다. 요청 이 완료된 후 반환된 값을 조회 하려면 이러한 비동기 메서드에 최종 매개변수로 전달된 콜백 객체 에서 onSuccess()
메서드를 구현 합니다. 요청 실패를 처리하다 하려면 onError()
메서드도 구현 해야 하지만 필수는 아닙니다.
Realm.getInstanceAsync(config, new Realm.Callback() { public void onSuccess( Realm realm) { Log.v("EXAMPLE", "Successfully fetched realm instance."); } public void onError(Exception e) { Log.e("EXAMPLE", "Failed to get realm instance: " + e); } });
Realm.getInstanceAsync(config, object : Realm.Callback() { override fun onSuccess(realm: Realm) { Log.v("EXAMPLE", "Successfully fetched realm instance.") } fun onError(e: java.lang.Exception) { Log.e("EXAMPLE", "Failed to get realm instance: $e") } })
App.Callback
함수 및 사용자 인증 과 같은 Atlas App Services를 쿼리할 때 비동기 호출은 App.Callback 유형의 최종 매개변수를 허용합니다. App.Result 유형의 단일 매개 변수를 허용하는 Lambda 함수를 사용하여 이 콜백을 처리할 수 있습니다. App.Callback
요청에서 반환된 값을 검색하려면 다음을 수행합니다.
콜백 함수에 전달된
App.Result
의isSuccess()
메서드를 사용하여 쿼리가 성공적으로 완료되었는지 확인합니다.쿼리가 성공한 경우
get()
메서드를 사용하여 쿼리 결과를 검색합니다. 쿼리가 실패한 경우getError()
를 사용하여 쿼리 실패의 원인이 된 예외를 검색합니다.
String appID = YOUR_APP_ID; // replace this with your App ID App app = new App(new AppConfiguration.Builder(appID) .build()); Credentials anonymousCredentials = Credentials.anonymous(); AtomicReference<User> user = new AtomicReference<User>(); app.loginAsync(anonymousCredentials, it -> { if (it.isSuccess()) { Log.v("AUTH", "Successfully authenticated anonymously."); user.set(app.currentUser()); } else { Log.e("AUTH", it.getError().toString()); } });
val appID = YOUR_APP_ID // replace this with your App ID val app: App = App( AppConfiguration.Builder(appID) .build() ) val anonymousCredentials: Credentials = Credentials.anonymous() var user: User? app.loginAsync(anonymousCredentials) { if (it.isSuccess) { Log.v("AUTH", "Successfully authenticated anonymously.") user = app.currentUser() } else { Log.e("AUTH", it.error.toString()) } }
RealmAsyncTask
영역에서 트랜잭션을 실행 하기 위한 비동기 호출은 RealmAsyncTask 인스턴스를 반환합니다. 비동기 호출에 추가 매개변수를 전달하여 RealmAsyncTask
에 대한 오류 핸들러 또는 성공 알림 을 선택적으로 지정할 수 있습니다. 또한 cancel() 메서드를 사용하여 트랜잭션이 완료되지 않도록 중지할 수 있습니다. RealmAsyncTask
에 전달된 Lambda 함수에는 트랜잭션에 포함할 쓰기 작업이 포함되어 있습니다.
// transaction logic, success notification, error handler all via lambdas realm.executeTransactionAsync(transactionRealm -> { Item item = transactionRealm.createObject(Item.class); }, () -> { Log.v("EXAMPLE", "Successfully completed the transaction"); }, error -> { Log.e("EXAMPLE", "Failed the transaction: " + error); }); // using class instances for transaction, success, error realm.executeTransactionAsync(new Realm.Transaction() { public void execute(Realm transactionRealm) { Item item = transactionRealm.createObject(Item.class); } }, new Realm.Transaction.OnSuccess() { public void onSuccess() { Log.v("EXAMPLE", "Successfully completed the transaction"); } }, new Realm.Transaction.OnError() { public void onError(Throwable error) { Log.e("EXAMPLE", "Failed the transaction: " + error); } });
// using class instances for transaction, success, error realm.executeTransactionAsync(Realm.Transaction { transactionRealm -> val item: Item = transactionRealm.createObject<Item>() }, Realm.Transaction.OnSuccess { Log.v("EXAMPLE", "Successfully completed the transaction") }, Realm.Transaction.OnError { error -> Log.e("EXAMPLE", "Failed the transaction: $error") }) // transaction logic, success notification, error handler all via lambdas realm.executeTransactionAsync( { transactionRealm -> val item = transactionRealm.createObject<Item>() }, { Log.v("EXAMPLE", "Successfully completed the transaction") }, { error -> Log.e("EXAMPLE", "Failed the transaction: $error") })
RealmResults
findAllAsync() 를 사용하여 Realm에서 비동기 읽기를 수행하면 즉시 빈 RealmResults 인스턴스가 반환됩니다. SDK는 백그라운드 스레드에서 쿼리를 실행하고 쿼리가 완료되면 RealmResults
인스턴스를 결과로 채웁니다. addChangeListener() 로 리스너를 등록하면 쿼리가 완료될 때 알림을 받을 수 있습니다.
RealmResults<Item> items = realm.where(Item.class).findAllAsync(); // length of items is zero when initially returned items.addChangeListener(new RealmChangeListener<RealmResults<Item>>() { public void onChange(RealmResults<Item> items) { Log.v("EXAMPLE", "Completed the query."); // items results now contains all matched objects (more than zero) } });
val items = realm.where<Item>().findAllAsync() // length of items is zero when initially returned items.addChangeListener(RealmChangeListener { Log.v("EXAMPLE", "Completed the query.") // items results now contains all matched objects (more than zero) })
RealmResultTask
Atlas에 대한 비동기 쿼리 는 RealmResultTask 인스턴스를 반환합니다. RealmAsyncTask
RealmResultTask
인스턴스를 취소할 수 있습니다. 다음을 사용하면 쿼리에서 반환된 값에 액세스할 수 있습니다.
get()을 사용하여 작업이 완료될 때까지 차단할 수 있습니다.
getAsync()를 사용하여 App.Callback 인스턴스를 통해 결과를 처리할 수 있습니다.
Document queryFilter = new Document("type", "perennial"); mongoCollection.findOne(queryFilter).getAsync(task -> { if (task.isSuccess()) { Plant result = task.get(); Log.v("EXAMPLE", "successfully found a document: " + result); } else { Log.e("EXAMPLE", "failed to find document with: ", task.getError()); } });
val queryFilter = Document("type", "perennial") mongoCollection.findOne(queryFilter) .getAsync { task -> if (task.isSuccess) { val result = task.get() Log.v("EXAMPLE", "successfully found a document: $result") } else { Log.e("EXAMPLE", "failed to find document with: ${task.error}") } }
코루틴
SDK는 콜백 대신 코루틴과 흐름을 사용하여 비동기적으로 요청할 수 있는 일련의 Kotlin 확장 기능 을 제공합니다. 이러한 확장을 사용 하여 트랜잭션을 실행 하고, 변경 사항을 감시하고, 읽고, 쓸 수 있습니다.
// open a realm asynchronously Realm.getInstanceAsync(config, object : Realm.Callback() { override fun onSuccess(realm: Realm) { Log.v("EXAMPLE", "Successfully fetched realm instance") CoroutineScope(Dispatchers.Main).launch { // asynchronous transaction realm.executeTransactionAwait(Dispatchers.IO) { transactionRealm: Realm -> if (isActive) { val item = transactionRealm.createObject<Item>() } } } // asynchronous query val items: Flow<RealmResults<Item>> = realm.where<Item>().findAllAsync().toFlow() } fun onError(e: Exception) { Log.e("EXAMPLE", "Failed to get realm instance: $e") } })