一、实现异步的基本方法
1.Java多线程基础知识
1)继承Thread
2) 实现Runnable接口
3)实现Callable接口 + FutureTask (拿到返回结果,处理异常)
4)线程池
简单举例
public static class Thread01 extends Thread{
@Override
public void run(){
System.out.println("当前线程"+Thread.currentThread().getId());
int i = 10 / 2;
System.out.println("运行结果"+i);
}
}
public static class Callable01 implements Callable<Integer> {
@Override
public Integer call(){
System.out.println("当前线程"+Thread.currentThread().getId());
int i = 10 / 2;
System.out.println("运行结果"+i);
return i;
}
}
@Test
public void thread() throws ExecutionException, InterruptedException {
System.out.println("main --- start");
System.out.println("当前线程"+Thread.currentThread().getId());
// 继承thread开启一个线程
// Thread01 thread01 = new Thread01();
// thread01.start();
// ======第三种方式
Callable01 callable01 = new Callable01();
FutureTask<Integer> integerFutureTask = new FutureTask<>(callable01);
new Thread(integerFutureTask).start();
//等待整个线程执行完成 获取返回结果
//Integer integer = integerFutureTask.get();
System.out.println("main --- end ");
}
2.js异步基础知识
2.1 首先Javascript语言的执行环境是"单线程"。也就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务。
这里面的关键在于一个任务队列,
当出现一个异步任务的时候会先将其放入任务队列里面排队,在任务结束时或者栈为空的时候,任务返回主线程。由此,单线程实现了异步。
2.2 代码的实现
方式一:使用setTimeout
方式二:使用原生的异步ajax
方式三:使用Promise
Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理且更强大。它最早由社区提出并实现,ES6将其写进了语言标准,统一了用法,并原生提供了Promise对象。
var promise = new Promise(function(resolve, reject){
// ... some code
if (/* 异步操作成功 */) {
resolve(value);
} else {
reject(error);
}
})
Promise实例生成后,可用then方法分别指定两种状态回调参数。then 方法可以接受两个回调函数作为参数:
Promise对象状态改为Resolved时调用 (必选)
Promise对象状态改为Rejected时调用 (可选)
方式四:async await
以同步的语义写出异步的代码,更易理解
二:CompletableFuture的使用
2.1创建异步操作
public static CompletableFuture<Void> runAsync(Runnable runnable)
public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor)
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor)
runAsync方法不支持返回值。
supplyAsync可以支持返回值。
2.2 thenAccept 消费处理结果
public CompletionStage<Void> thenAccept(Consumer<? super T> action);
public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action);
public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action,Executor executor);
CompletableFuture的使用这部分参考了 https://www.jianshu.com/p/6bac52527ca4
3.使用场景说明
3.1 java多个查询操作耗时时可以选择异步编排
代码如下
/**
* 查询页面详细内容
*/
@Override
public SkuItemVo item(Long skuId) throws ExecutionException, InterruptedException {
SkuItemVo skuItemVo = new SkuItemVo();
CompletableFuture<SkuInfoEntity> infoFutrue = CompletableFuture.supplyAsync(() -> {
//1 sku基本信息
SkuInfoEntity info = getById(skuId);
skuItemVo.setInfo(info);
return info;
}, executor);
CompletableFuture<Void> saleAttrFuture =infoFutrue.thenAcceptAsync(res -> {
//2 获取spu销售属性组合
List<ItemSaleAttrVo> saleAttrVos = skuSaleAttrValueService.getSaleAttrsBuSpuId(res.getSpuId());
skuItemVo.setSaleAttr(saleAttrVos);
},executor);
CompletableFuture<Void> descFuture = infoFutrue.thenAcceptAsync(res -> {
//3 获取spu介绍
SpuInfoDescEntity spuInfo = spuInfoDescService.getById(res.getSpuId());
skuItemVo.setDesc(spuInfo);
},executor);
// 等待所有任务都完成再返回
CompletableFuture.allOf(ImgageFuture,saleAttrFuture,descFuture).get();
return skuItemVo;
}
descFuture 和saleAttrFuture 放在在获取到infoFutrue 的结果后异步执行完成异步编排;
3.2 js异步应用实例
js方面异步使用最多的ajax 请求数据;
// 初始获取数据
async getFirstData() {
try {
const params = { };
const data = await this.getTasks(params);
} catch (error) {
console.log(error);
}
},
async 和await 的一个组合;