异步 API - Java SDK
Java SDK 允许您以两种方式访问网络和磁盘资源:同步和异步。同步(或“sync”)请求会阻止执行,直到请求返回成功或失败;异步(或“async”)请求会分配 回调,并继续执行下一行代码。当请求返回时,运行 回调 以处理结果。在 回调 中,您可以检查请求是否成功执行,并访问返回的结果或返回的错误。
异步调用
SDK 中的异步 API 请求以后缀“Async”结尾。异步请求有几种不同的行为方式,具体取决于您使用的是 SDK 的哪一部分。
Realm.Callback
打开域的异步调用(无论是否启用同步)均使用类型为 Realm的最终参数。 要在请求完成后检索返回的值,请在作为最终参数传递给这些异步方法的回调对象中实现 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类型的最终参数。 您可以使用接受单个Lambda App.Result 类型参数的 函数来处理此回调。要从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
在 Realm 上执行事务的异步调用会返回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的实例。 您可以取消RealmResultTask
RealmAsyncTask
实例,就像取消 一样。要访问查询返回的值,可以使用:
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") } })