使用回调将多个异步调用排队

明智的土豆

我需要从图库中获取一些图像,对其进行处理(调整大小,压缩...)并将其保存到特定路径。但是,我需要将呼叫排队,因为较旧的设备将无法同时处理多个图像。

我正在使用Glide,这是用于处理一张图片的代码:

fun processImage(context: Context, sourcePath: String, destinationPath: String, quality: Int, width: Int, height: Int, deleteOriginal: Boolean, callback: ((success: Boolean) -> Unit)) {
    val sourceFile = File(sourcePath)
    val destinationFile = File(destinationPath)

    GlideApp.with(context)
            .asBitmap()
            .load(sourceFile)
            .into(object : SimpleTarget<Bitmap>(width, height) {
                override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
                    try {
                        destinationFile.writeBytes(ImageUtilities.imageToByteArray(resource, quality, Bitmap.CompressFormat.JPEG, false))
                        if (deleteOriginal) {
                            val originalFile = File(sourcePath)
                            originalFile.delete()
                        }
                        callback.invoke(true)
                    } catch (ex: Exception) {
                        callback.invoke(false)
                    }
                }
            })
}

现在,我通过processNextImage递归调用自身来手动排队呼叫,直到所有图像都被处理为止:

private fun processImages(sourceImagePaths: List<String>) {
        processNextImage(sourceImagePaths, 0)
}

private fun processNextImage(sourceImagePaths: List<String>, index: Int) {
    val imagePath = sourceImagePaths[index]
    val destination = FileUtilities.generateImagePath()
    processImage(this, imagePath, destination, 90, 1000, 1000, false) {
        processedImagePaths.add(destination)
        if (index + 1 < sourceImagePaths.count())
            processImage(sourceImagePaths, index + 1)
        else
            success()
    }
}

但是我不认为这是最好的方法,我尝试研究Kotlin协程,但是我发现的只是队列代码已经被阻塞时的示例,这不适合我的情况,因为Glide已经异步处理了调整大小并在回调中返回结果 onResourceReady

有什么干净的方法可以做到这一点吗?

马克·托波尼克(Marko Topolnik)

官方文档所述,如果要将基于回调的API转换为基于可挂起的函数的API,可以采用一种简单的模式。我将在这里解释该描述。

您的关键工具是来自标准库的函数suspendCoroutine()假设您具有someLongComputation带有接收Result对象的回调的函数:

fun someLongComputation(params: Params, callback: (Result) -> Unit)

您可以使用以下简单的代码将其转换为挂起函数:

suspend fun someLongComputation(params: Params): Result = 
    suspendCoroutine { cont ->
        someLongComputation(params) { cont.resume(it) }
} 

请注意,传递给原始回调的对象的类型如何仅变为可挂起函数的返回值。

有了它,您可以看到协程的魔力就在您的眼前发生:即使它看起来完全像是阻塞呼叫,但事实并非如此。协程将在后台挂起,并在返回值准备就绪时恢复运行-它将如何恢复完全由您控制。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

已使用异步调用回调?

Javascript - 在从函数返回之前等待异步调用完成,不使用回调

使用Rhino从Java方法异步调用JavaScript回调

使用异步调用设计函数回调

访问异步调用的回调参数

多次异步调用后回调?

在Redux中使用多个异步调用设置初始状态

如何处理来自带有回调的多个ajax异步调用的数据?

使用回调接口的AsyncTask实现-在单个回调接口中处理多个调用响应

PHP 异步调用多个函数

C ++中的多个异步调用

对mongolab运行多个异步调用失败

等待多个异步调用完成?

如何返回多个异步调用的响应?

如何使用 React JS 为从辅助方法到 componentDidMount 的异步调用编写回调函数

C#LanguageExt-将多个异步调用合并为一个分组的调用

ComponentWillReceiveProps使用多个同步调度调用一次,但是使用异步调度多次调用吗?

caolon异步-永远不会调用回调

在异步函数中不调用回调等效于什么?

将异步调用传递给 Firestore

如何使用参数调用回调函数

javascript-使用参数调用回调

如何使用参数调用回调函数?

从readline的线路回调中进行异步调用?

Nodejs异步调用排水回调完成之前

使用Rx Java Observable一次进行多个异步调用(触发并忘记调用)

单元测试多个异步调用,这些调用使用Mocha返回承诺

是否应该根据CPU数量将异步调用分成多个块?

使用Java线程进行异步调用