-
循环中调用异步接口获取数据
2020-07-17 10:07:33遇到这样一个需求:调用接口,返回一个新闻列表,再循环这个新闻列表,用每个新闻的id异步请求这个新闻的视频地址,这就需要在循环里调用接口。如果用for循环,接口还没请求完成,for循环就已经执行完了。所以改成...前言
遇到这样一个需求:调用接口,返回一个新闻列表,再循环这个新闻列表,用每个新闻的id异步请求这个新闻的视频地址,这就需要在循环里调用接口。如果用for循环,接口还没请求完成,for循环就已经执行完了。所以改成promise去处理。
开始
整体思路就是:先存数组,然后循环生成每一个promise,然后用promise.all来调用,then的时候返回的是一个结果数组。
1、首先定义循环里的异步请求
getInfo(item ,index){ return new Promise((resolve,reject) => { axios.post('/videoUrl',{id:item.id}).then(res=>{ let url = res.data; resolve({id:item.id,url:url}) }) }) }
2、newsList为开始接口获取的新闻列表,对新闻列表进行循环,得到一个promise数组。
let promiseArr = this.newsList.map((item,index) => { return this.getInfo(item, index) })
3、用promise.all来调。
Promise.all(promiseArr).then(value=>{ console.log(value); //value:[{id: 1, url: "xxxxx"}, // {id: 2, url: "xxxxx"}, // {id: 3, url: "xxxxx"}] this.newsList = value; })
这样就拿到了包含新闻视频地址的新闻列表。
全部代码
<script> export default { name: 'empty', data () { return { newsList:[]//新闻列表 } }, methods:{ getNewsList(){ axios.get('/newsList').then(res=>{ this.newsList = res.data;//newsList = [{id:1},{id:2},{id:3}]; let promiseArr = this.newsList.map((item,index) => { return this.getInfo(item, index) }) Promise.all(promiseArr).then(value=>{ console.log(value); //value:[{id: 1, url: "xxxxx"}, // {id: 2, url: "xxxxx"}, // {id: 3, url: "xxxxx"}] this.newsList = value; }) }) }, // 通过新闻id请求新闻视频地址 getInfo(item ,index){ return new Promise((resolve,reject) => { axios.post('/videoUrl',{id:item.id}).then(res=>{ let url = res.data; resolve({id:item.id,url:url}) }) }) } }, mounted(){ this.getNewsList(); } } </script>
后记
1、首先关于后台修改接口,正常返回应该是newsList里就返回了视频地址,协商过就是需要单独去调用。
2、这个问题的解决花费了时间,特此记录。文章参考javascript for循环+异步请求导致请求顺序不一致 -
c++ 异步下获取线程执行结果_异步编排(CompletableFuture异步调用)
2020-11-23 23:57:421、问题背景问题:当查询接口较复杂时候,数据的获取都需要远程调用,必然需要花费更多的时间。假如查询文章详情页面,需要如下标注的时间才能完成:那么,用户需要4s后才能统计的数据。很显然是不能接受的。如果有...1、问题背景
问题:当查询接口较复杂时候,数据的获取都需要远程调用,必然需要花费更多的时间。
假如查询文章详情页面,需要如下标注的时间才能完成:
那么,用户需要4s后才能统计的数据。很显然是不能接受的。
如果有多个线程同时完成这4步操作,也许只需要1s左右即可完成响应。
2、CompletableFuture介绍
在Java 8中, 新增加了一个包含50个方法左右的类: CompletableFuture,提供了非常强大的Future的扩展功能,可以帮助我们简化异步编程的复杂性,提供了函数式编程的能力,可以通过回调的方式处理计算结果,并且提供了转换和组合CompletableFuture的方法。
CompletableFuture类实现了Future接口,所以你还是可以像以前一样通过
get
方法阻塞或者轮询的方式获得结果,但是这种方式不推荐使用。CompletableFuture和FutureTask同属于Future接口的实现类,都可以获取线程的执行结果。
2.1 创建异步对象 CompletableFuture 提供了四个静态方法来创建一个异步操作。
没有指定Executor的方法会使用ForkJoinPool.commonPool() 作为它的线程池执行异步代码。如果指定线程池,则使用指定的线程池运行。以下所有的方法都类同。
•runAsync方法不支持返回值。•supplyAsync可以支持返回值。
2.2 计算完成时回调方法
当CompletableFuture的计算结果完成,或者抛出异常的时候,可以执行特定的Action。主要是下面的方法:
whenComplete可以处理正常和异常的计算结果,exceptionally处理异常情况。BiConsumer super T,? super Throwable>可以定义处理业务
whenComplete 和 whenCompleteAsync 的区别:
whenComplete:是执行当前任务的线程执行继续执行 whenComplete 的任务。whenCompleteAsync:是执行把 whenCompleteAsync 这个任务继续提交给线程池来进行执行。
方法不以Async结尾,意味着Action使用相同的线程执行,而Async可能会使用其他线程执行(如果是使用相同的线程池,也可能会被同一个线程选中执行)
2.3 线程串行化方法
thenApply 方法:当一个线程依赖另一个线程时,获取上一个任务返回的结果,并返回当前任务的返回值。
thenAccept方法:消费处理结果。接收任务的处理结果,并消费处理,无返回结果。
thenRun方法:只要上面的任务执行完成,就开始执行thenRun,只是处理完任务后,执行 thenRun的后续操作
带有Async默认是异步执行的。这里所谓的异步指的是不在当前线程内执行。
Function super T,? extends U>
T:上一个任务返回结果的类型
U:当前任务的返回值类型
2.4 多任务组合
allOf:等待所有任务完成
anyOf:只要有一个任务完成
3、例子
上面例子完美呈现,计算完成时回调方法
CompletableFuture.supplyAsync()
、线程串行化方法articleCompletableFuture.thenAcceptAsync()
、创建异步对象CompletableFuture.runAsync()
、多任务组合CompletableFuture.allOf()
。 -
dubbo学习笔记---dubbo中的异步调用
2020-10-18 23:34:32这种方式主要应用于提供者接口响应耗时明显,消费者端可以利用调用接口的时间去做一些其他的接口调用,利用 Future 模式来异步等待和获取结果即可。 这种方式可以大大的提升消费者端的利用率。 目前这种方式可以通过...dubbo学习笔记—dubbo中的异步调用
1. 异步调用
- Dubbo不只提供了堵塞式的的同步调用,同时提供了异步调用的方式。这种方式主要应用于提供者接口响应耗时明显,消费者端可以利用调用接口的时间去做一些其他的接口调用,利用 Future 模式来异步等待和获取结果即可。
- 这种方式可以大大的提升消费者端的利用率。 目前这种方式可以通过XML的方式进行引入。
2. 异步调用的实现
-
为了能够模拟等待,通过 int timeToWait参数,标明需要休眠多少毫秒后才会进行返回。
String sayHello(String name, int timeToWait);
-
接口实现为了模拟调用耗时 可以让线程等待一段时间
-
在消费者端,配置异步调用 注意消费端默认超时时间1000毫秒 如果提供端耗时大于1000毫秒会出现超时,可以通过改变消费端的超时时间 通过timeout属性设置即可单位毫秒
<dubbo:reference id="helloService" interface="com.lagou.service.HelloService"> <dubbo:method name="sayHello" async="true" /> </dubbo:reference>
-
测试,我们休眠100毫秒,然后再去进行获取结果。方法在同步调用时的返回值是空,我们可以通过RpcContext.getContext().getFuture() 来进行获取Future对象来进行后续的结果等待操作。
3. 异步调用的特殊说明
- 需要特别说明的是,该方式的使用,请确保dubbo的版本在2.5.4及以后的版本使用。
- 原因在于在2.5.3及之前的版本使用的时候,会出现异步状态传递问题。
- 比如我们的服务调用关系是 A -> B -> C , 这时候如果A向B发起了异步请求,在错误的版本时,B向C发起的请求也会连带的产生异步请求。
- 这是因为在底层实现层面,他是通过 RPCContext 中的attachment 实现的。在A向B发起异步请求时,会在 attachment 中增加一个异步标示字段来表明异步等待结果。
- B在接受到A中的请求时,会通过该字段来判断是否是异步处理。但是由于值传递问题,B向 C发起时同样会将该值进行传递,导致C误以为需要异步结果,导致返回空。
- 这个问题在2.5.4及以后的版本进行了修正。
- 修正链接:https://github.com/apache/dubbo/blob/47ee52d122fb6f0462ed99530cfe462c591feac8/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ContextFilter.java#L70-L71
-
dubbo-8:异步调用
2020-12-20 16:21:25待和获取结果即可。这种方式可以大大的提升消费者端的利用率。 目前这种方式可以通过XML的方式进 行引入。 1、模拟等待 为了能够模拟等待,通过 int timeToWait参数,标明需要休眠多少毫秒后才会进行返回。 public ...官方说明
Dubbo不只提供了堵塞式的的同步调用,同时提供了异步调用的方式。这种方式主要应用于提供者接口
响应耗时明显,消费者端可以利用调用接口的时间去做一些其他的接口调用,利用 Future 模式来异步等
待和获取结果即可。这种方式可以大大的提升消费者端的利用率。 目前这种方式可以通过XML的方式进
行引入。1、模拟等待
为了能够模拟等待,通过 int timeToWait参数,标明需要休眠多少毫秒后才会进行返回。
public interface HelloService { String sayHello(String name, int timeToWait); }
2、接口实现
为了模拟调用耗时 可以让线程等待一段时间
public class HelloServiceImpl implements HelloService { public String sayHello(String name, int timeToWait) { try { Thread.sleep(timeToWait); } catch (InterruptedException e) { e.printStackTrace(); } return "hello1111:"+name; } }
3、消费者端
配置异步调用
注意消费端默认超时时间1000毫秒 如果提供端耗时大于1000毫秒会出现超时。可以通过改变消费端的超时时间 通过timeout属性设置即可单位毫秒<dubbo:method name="sayHello" async="true"/>
完整如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 --> <dubbo:application name="service-consumer" > <dubbo:parameter key="qos.enable" value="true" ></dubbo:parameter> <dubbo:parameter key="qos.port" value="33333"></dubbo:parameter> <!-- value为true:talnet用ip登录之后可以操作,否则只能登录不能操作--> <dubbo:parameter key="qos.accept.foreign.ip" value="true" ></dubbo:parameter> </dubbo:application> <!-- 使用multicast广播注册中心暴露发现服务地址 --> <dubbo:registry address="zookeeper://127.0.0.1:2181" /> <!-- 生成远程服务代理,可以和本地bean一样使用demoService --> <dubbo:reference id="helloService" interface="com.lagou.service.HelloService" > <!-- 设置方法是否异步调用 :默认是false。 TODO 注意:方法在异步调用时的返回值是空,我们可以通过 RpcContext.getContext().getFuture() 获取Future对象,来进行后续的结果等操作 --> <dubbo:method name="sayHello" async="true"/> </dubbo:reference> </beans>
4、测试
我们休眠100毫秒,然后再去进行获取结果。方法在同步调用时的返回值是空,我们可以通过 RpcContext.getContext().getFuture() 来进行获取Future对象来进行后续的结果等待操作。
package com.lagou; import com.lagou.service.HelloService; import org.apache.dubbo.rpc.RpcContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.io.IOException; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; public class XMLConsumerMain { public static void main(String[] args) throws IOException, ExecutionException, InterruptedException { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:dubbo-comsumer.xml"); System.out.println("Consumer 启动成功!"); HelloService helloService = (HelloService) context.getBean("helloService"); System.out.println("获取接口成功!"); while (true) { System.in.read(); String result = helloService.sayHello("haha哈喽", 100); // 利用Future 模式来获取 Future<Object> future = RpcContext.getContext().getFuture(); System.out.println("result:" + result); System.out.println("future===》result:" + future.get()); } } }
5、注意
方法在异步调用时的返回值是空,我们可以通过 RpcContext.getContext().getFuture() 获取Future对象,来进行后续的结果等操作。详见第4步测试类中的具体代码
-
利用Future异步获取多线程的返回结果
2016-08-29 12:11:05Future接口是Java标准API的一部分,在java.util.concurrent包中。Future接口是Java线程Future模式的实现,可以来进行异步...在途中遇到一个问题,那就是虽然能异步获取结果,但是Future的结果需要通过isdone来判断是否 -
Java8多线程异步调用 CompletableFuture 详解
2019-07-09 07:13:31Future是Java 5添加的类,用来描述一个异步计算的结果,但是获取一个结果时方法较少,要么通过轮询isDone,确认完成后,调用get()获取值,要么调用get()设置一个超时时间。但是这个get()方法会阻塞住调用线程,这种... -
java8多线程异步调用 CompletableFuture 详解
2019-02-16 10:51:45Future是Java 5添加的类,用来描述一个异步计算的结果,但是获取一个结果时方法较少,要么通过轮询isDone,确认完成后,调用get()获取值,要么调用get()设置一个超时时间。但是这个get()方法会阻塞住调用线程,这种... -
sprngboot使用@Async实现异步调用二:使用Future以及定义超时
2019-06-10 20:25:03文章目录1. Tips:什么是Future类型?2. 正常用future的get(long timeout, ...Future是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果的接口。必要时可以通过get方法获取执行结... -
java 利用Future异步获取多线程任务结果
2019-03-28 16:51:52Future接口是Java标准API的一部分,在java.util.concurrent包中。Future接口是Java线程Future模式的实现,可以来...在途中遇到一个问题,那就是虽然能异步获取结果,但是Future的结果需要通过isdone来判断是否有结... -
java异步调用future、callable以及futuretask分析
2018-09-29 09:34:15通过线程池的submit方法和实现了callable接口的对象,可以返回一个future接口的对象,通过此对象可以异步获取callable方法的运行结果。 future.get() 阻塞式的返回结果,如果任务未执行完毕,就阻塞等待结果产生。 ... -
异步调用轻量级封装AsynCaller
2005-09-23 09:44:00当UI动作引发一个耗时的计算时,我们经常需要将这个耗时的过程放到后台线程中去完成,然后获取该过程的结果。使用.NET提供的默认设施,无论是... AsynCaller通过事件来通知外部异步调用的结果,IAsynCaller接口如下... -
vue调用接口同步实现
2021-02-25 11:40:37实现字典项数据后端获取,始终无法同步返回结果,在网上找了好多vue同步接口的方法,都是说在方法前加async,在接口名前加await,自己试了好长时间也不好使,最终只能选择用回调函数的方法来达到方法的同步调用,回... -
created不能异步_mpvue里created里异步请求结果,如何在beforeMount里获取到呢
2021-01-13 04:54:15我想在created里获取到这两个结果,存在storage里在beforeMount里调用,可是不能行之前我是直接用new Promise一路then下来,最后一个then里调用轮播方法传进去openId和token,想问下还有别的方... -
登录功能(调用接口)
2020-06-01 15:06:32//获取项目名 function sysName(){ var pathName = window.document.location.pathname; var projectName = pathName.substring(0,pathName.substr(1).indexOf('/')+1); return (projectName); } -
异步操作优化接口性能,可提升数倍
2021-01-14 16:50:18背景: 在我们日常的开发中,很多时候我们的接口会有比较复杂的...比如有这样的场景,我们需要去调用三个第三方的api获取结果后并且相加,每个api大概需要花2s 代码: public int getA(){ try { Thread.sleep(2000); -
第4章 接口调用方式
2020-11-17 12:11:16第4章 接口调用方式 接口调用方式 ...得到异步任务正确的结果 .catch() 获取异常信息 .finally() 成功与否都会执行(不是正式标准) 静态方法 .all() Promise.all 方法接受一个数组作参数,数组中的对象 -
NodeJS中常见异步接口定义(get、post、jsonp)
2016-05-02 16:35:00再次强调ajax和jsonp是两个概念,但是由于jquery的封装,使这两种异步接口的调用方式,看起来比较相近,但在底层差别还是比较大的(本文只写服务端的实现)。 为了便于讲解我使用express框架来运行我的demo。并...
-
junit-4.11和hamcrest-core-1.3 的jar包
-
MASK LBP代币拍卖共募集近4000万美元
-
2018年城乡建设统计年鉴.rar
-
网络连接-接收数据(UDP)
-
win7 U盘中文件夹无法删除,粉碎后有出现且改变了文件名的处理方法,实测有效
-
MySQL Router 实现高可用、负载均衡、读写分离
-
程序员命名规则
-
Python启蒙到架构师的核心技术精讲课程
-
自动化测试Python3+Selenium3+Unittest
-
亚马逊云ECyum跟新记录(排坑记录)
-
基于样本对的稀疏表示分类用于人脸识别
-
modbus_example.rar
-
虚幻4引擎基础
-
MySQL NDB Cluster 负载均衡和高可用集群
-
液晶光控取向技术进展
-
如何释放苹果Mac上的储存空间?
-
2.2-实例2-Python蟒蛇绘制.pptx
-
android获取网络代理
-
移除本地文件夹与git仓库的链接
-
MaxScale 实现 MySQL 读写分离与负载均衡