首页 > 其他分享 >结合回调函数处理异步任务结果

结合回调函数处理异步任务结果

时间:2024-09-07 13:23:55浏览次数:11  
标签:异步 函数 结果 处理 任务 CompletableFuture 回调

结合回调函数处理异步任务结果的过程可以比作在等待一份重要的快递时安排一个通知服务。这个通知服务就是回调函数,它会在快递送达时通知你,或者在处理完成后执行特定的操作。


在 Java 的 CompletableFuture 中,这种模式可以通过 supplyAsync() 、thenApply()、thenAccept() 和 handle() 方法来实现。


创建一个异步任务时,使用 CompletableFuture.supplyAsync() 可以启动一个任务,这个任务在后台线程中执行,直到它完成。假设有一个任务需要从远程服务器获取数据:


// supplyAsync() 方法接收一个 Supplier 函数,这个函数会在后台线程中运行,并返回一个结果

// 结果会被封装在 CompletableFuture 对象中,等待进一步处理

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {

   // 模拟从远程服务器获取数据

   try {

       Thread.sleep(3000);

   } catch (InterruptedException e) {

       e.printStackTrace();

   }

   return "数据已成功获取";

});


使用 thenApply() 方法,可以在异步任务完成后,对结果进行转换。这个方法接收一个 Function 函数,这个函数会接收任务的结果,并返回一个新结果。比如,将获取的数据进行处理:


// thenApply() 方法将原始数据转换为大写形式

// 处理后的结果会成为新的 CompletableFuture 对象的结果

CompletableFuture<String> processedFuture = future.thenApply(result -> {

   // 对结果进行处理

   return result.toUpperCase();

});


为了执行一个操作而不关心处理的结果,可以使用 thenAccept() 方法。这个方法接收一个 Consumer 函数,它处理任务完成时的结果,可以在异步任务完成时执行一些操作,比如日志记录或通知用户。例如,将结果打印到控制台:


// 在任务完成后会调用传入的 Consumer 函数,并将结果传递给它

future.thenAccept(result -> {

   System.out.println("任务完成,结果是:" + result);

});


在任务执行过程中,可能会遇到异常。handle() 方法可以用来处理这些异常,它接收一个 BiFunction 函数,这个函数接收结果和异常(如果有的话),并返回一个处理后的结果。例如:


// handle() 方法检查是否有异常发生

// 如果有异常,它会处理异常并返回一个默认的结果

// 如果没有异常,它会处理正常的结果

CompletableFuture<String> handledFuture = future.handle((result, ex) -> {

   if (ex != null) {

       // 处理异常

       System.out.println("任务发生错误:" + ex.getMessage());

       return "错误处理结果";

   }

   // 处理正常结果

   return result.toLowerCase();

});


对于这四种回调函数,可以使得异步任务的结果处理变得灵活而强大。通过结合使用不同的回调函数,可以对异步任务的结果进行多种操作,保证程序在处理复杂任务时仍然保持清晰和高效。


4 如何组合并处理多个 CompletableFuture?

组合和处理多个 CompletableFuture 可以让并发任务变得更加灵活和高效。设想有多个任务需要并行执行,然后将它们的结果结合起来进行进一步处理。


在进行组合时,最基本的方法之一是将多个 CompletableFuture 的结果合并。比如,有两个任务需要并行完成,获取两个不同的数据源,然后将这两个结果结合起来。


可以使用 thenCombine() 方法,它接收两个 CompletableFuture 和一个合并函数,两个 CompletableFuture 必须在相同的线程池中执行。


假设有两个任务分别从不同的 API 获取数据:


CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {

   // 模拟从第一个 API 获取数据

   return "数据1";

});


CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {

   // 模拟从第二个 API 获取数据

   return "数据2";

});


为了将这两个结果结合起来,可以使用 thenCombine():


// thenCombine() 方法接收两个 CompletableFuture 和一个函数,这个函数将两个任务的结果合并成一个结果

// 最终的结果是将两个字符串连接在一起

CompletableFuture<String> combinedFuture = future1.thenCombine(future2, (result1, result2) -> {

   // 将两个结果结合成一个

   return result1 + " 和 " + result2;

});


另一个有用的方法是 allOf()方法。当有多个任务需要并行执行,并且在所有任务完成后执行某个操作时,allOf() 非常有用。它接收一个 CompletableFuture 数组,并在所有这些 CompletableFuture 完成时触发。可以用来等待多个异步任务完成,然后执行某个操作:


CompletableFuture<Void> allOfFuture = CompletableFuture.allOf(future1, future2);

1

要获取所有任务的结果,可以在 allOf() 的结果上添加一个回调函数:


// thenRun() 方法会在所有任务完成后执行,它不需要处理结果,只是执行某个操作

allOfFuture.thenRun(() -> {

   // 处理所有任务完成后的操作

   try {

       String result1 = future1.get();

       String result2 = future2.get();

       System.out.println("任务1的结果: " + result1);

       System.out.println("任务2的结果: " + result2);

   } catch (InterruptedException | ExecutionException e) {

       e.printStackTrace();

   }

});


标签:异步,函数,结果,处理,任务,CompletableFuture,回调
From: https://blog.51cto.com/u_16270801/11944676

相关文章

  • SQL 自定义函数 生成网卡地址,MES开发中经常会用到的
    SQL自定义函数生成网卡地址,MES开发中经常会用到的ALTERFunction[dbo].[Fun_ReleaseMACadd]( @CurrentSeqNovarchar(6))Returnsvarchar(18)-------------------------------------------------------------------------------------------------As--------------......
  • 字符串查找函数strchr 、 strrchr和strstr的简介
    目录一、函数简介1.1. strchr 函数1.2.strrchr函数1.3. strstr 函数二、函数原型2.1. strchr 函数参数返回值2.1. strchr 函数参数返回值2.2. strstr 函数参数返回值三、函数实现(伪代码)3.1.strchr实现3.2.strrchr实现3.3. strstr实现四、......
  • C++:构造函数、析构函数
    目录一、类的默认成员函数二、构造函数构造函数的特点三、析构函数析构函数的特点一、类的默认成员函数    默认成员函数就是用户没有显式实现,编译器会自动生成的成员函数称为默认成员函数,一个类,我们不写的情况下编译器会默认生成以下6个默认成员函数,默认成员函......
  • Excel--FILTER函数
    FILTER函数=FILTER(查询区域,条件,查不到结果返回的值)FILTER函数是一个筛选函数,可根据指定条件筛选出一个或多少数据。单条件筛选:下面为只筛选一个条件性别为女多条件筛选:+连接两个筛选条件,相当于”或“,其中一个条件成立既可以被筛选出来*连接两个筛选条件,相当于”......
  • c语言内存函数
    今天来学习C语言中的内存函数目录1.memcpy代码形式示例运行结果2.memmove代码形式示例运行结果3.memset代码形式示例运行结果4.memcmp形式示例运行结果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/b7d8d59577b248deaa7b869d014d8b4f.png#pic_center)5......
  • 写一个函数判断整数在系统的储存方式为大端还是小端
    1.何为大小端。所谓大小端就是一个整形在电脑系统中以十六进制的储存方式,当一个数据超过一个字节时在内存中储存顺序会有所不同,按照不同的顺序我们分为大小端两种,大端的低字节保存在高位,小端的低字节保存在低端。例如1在系统中的储存方式有小端储存(0x00000001)   ......
  • Python中的`super()`函数:解锁面向对象编程的高级技巧
    引言在面向对象的世界中,继承是一个非常重要的概念。通过继承,我们可以创建新的类来复用现有类的功能,同时还可以根据需求添加或修改功能。然而,在复杂的继承体系中,正确地调用基类的方法变得尤为重要。super()函数正是为此而生,它提供了一种简洁有效的方式来处理这类问题。本文将带你深......
  • C语言中有关函数的知识
        前言        C语言函数是一种函数,用来编译C语言,一般包括字符库函数,数学函数,目录函数,进程函数,诊断函数,操作函数等    这里这个函数和我们高中时期学的函数类似,高中的函数是这样    F(x)=5x+21                   ......
  • 什么是nginx的异步非阻塞
    Nginx是一个高性能的Web服务器和反向代理服务器,采用了异步非阻塞的I/O模型,这种设计使其在处理大量并发连接时表现出色。以下是对Nginx的异步非阻塞模型的详细解释:异步非阻塞I/O模型1.异步定义:在异步I/O模型中,任务的执行与结果的获取是分开的。当一个请求被发送出去......
  • MySQL 日期函数语法介绍和案例示范以及常见问题解决
    本文将以电商交易系统为例,详细讲解MySQL日期类型及其转化,常用的日期函数,以及一些解决常见问题的方案。一、MySQL日期数据类型MySQL提供了多种日期数据类型,适用于不同的使用场景。常见的日期类型包括DATE、DATETIME、TIMESTAMP、TIME和YEAR。DATE:只存储日期,不包含......