当前位置:网站首页>JS不使用async/await解决数据异步/同步问题
JS不使用async/await解决数据异步/同步问题
2022-07-17 05:23:00 【£漫步 云端彡】
axios解决同步问题的方式
至今我能想到的解决同步/异步问题的三种方式如下:
- 通过函数回调解决同步异步。这种方式代码书写层层嵌套不直观。
- async/await关键字,这两个关键字搭配使用完美解决同步/异步问题,但是这种方式并不能说是解决了同步问题,而是说将异步功能延续到了调用者,即父方法。当然这种方式在调用方本身就是异步函数的情况下有效。
- 利用引用变量的方式解决同步异步问题。这种方式完美解决了第2种方式存在的问题,调用方可以是同步方法。但是该种方式不能解决基本类型,因为基本类型不是使用引用变量的。可通过将基本类型包装在对象中,解决这个问题。
以上三种方式各有利弊,具体情况使用具体方式。下面通过示例模拟一下上述三种方式。
回调解决
正常情况下:
// 模拟异步发数据 function req(str) { return new Promise((resolve, reject) => { resolve(str) }) } // 请求方法 function update(data) { req(data).then(result => { str = result; // 代码更新后区域 console.log("结果3:" + str); // 代码1 }); console.log("结果1:" + str); // 代码2 } let str = "你好"; // 代码3 update("hello"); // 代码4 console.log("结果2:" + str); // 代码5结果:

分析:代码3,之后,执行代码4,其中并不会立刻执行代码1,而是执行方法内部的代码2和之后跳出代码5。因为req(data).then()是异步的,等异步请求结束后之行代码1,因此写在代码1区域能够解决实际问题,少量回调,这个方式很方便,多次回调时,降低了代码的可读性。
async/await关键字
// 模拟异步发数据 function req(str) { return new Promise((resolve, reject) => { resolve(str) }) } // 请求方法,通过声明async/await,可等待异步完成之后再执行 async function update(data) { await req(data).then(result => { str = result; console.log("结果2:" + str); // 代码1 }); // 代码更新后区域 console.log("结果3:" + str); // 代码2 } let str = "你好"; // 代码3 update("hello"); // 代码4 console.log("结果1:" + str); // 代码5结果:

步骤:第一步将父级方法也就是update,声明为异步方法(async),然后再需要等待同步的地方标注为await,这样即可等待req(data).then()请求执行成功之后,再执行下面代码。注意:async必不可少,否则报错。
分析:代码执行完3时,因为代码4声明为异步了,故先执行了代码5,执行请求时,发现请求为等待,故等then执行结束后,即执行了代码1,最后执行了代码2。所以代码2区域能够解决实际问题。虽然这样是解决了update方法内部的同步代码问题,但是变相的将异步问题向上拋了。update方法为异步了。利用引用变量的方式解决同步异步问题
下面使用新的示例,因为字符串不是使用引用的方式,需要将字符串包裹在对象中才起作用。先看正常的示例:// 模拟异步发数据 function req(obj) { return new Promise((resolve, reject) => { resolve(obj) }) } // 请求方法,通过声明async/await,可等待异步完成之后再执行 function update(data) { req(data).then(result => { obj = result; console.log("结果3:",obj); // 代码1 }); console.log("结果1:",obj); // 代码2 } let obj = { msg: "你好" }; // 代码3 update({ msg: "hello" }); // 代码4 console.log("结果2:",obj); // 代码5结果:

分析:不用多说,代码执行顺序为:代码3、4、2、5、1。执行代码2和5时,obj其实是一个引用,因此这两个结果是一样的,但是,赋值使用obj = result,结果2之前将obj引用到了新的对象,因此执行结果2最后和之前不一样。
问题:怎么样才能将结果1和结果2的值和结果3是一样的呢?
方案:这是赋值的问题,因此obj = result的意思是将obj指向了新的引用对象,之前的丢弃。所以在赋值的时候,不要丢弃之前的对象,只是做修改对象内部属性的值,那么不管再哪里引用都是一样的值了。// 模拟异步发数据 function req(obj) { return new Promise((resolve, reject) => { resolve(obj) }) } // 请求方法,通过声明async/await,可等待异步完成之后再执行 function update(data) { req(data).then(result => { // 只赋值属性的值,不改变引用地址 obj.msg = result.msg; console.log("结果3:",obj); // 代码1 }); console.log("结果1:",obj); // 代码2 } let obj = { msg: "你好" }; // 代码3 update({ msg: "hello" }); // 代码4 console.log("结果2:",obj); // 代码5结果:

分析:如结果所示,最后的数据为实时的数据,但是上面的打印数据是代码执行时的值,而我们平时调用获取值时,都是使用引用来获取变量的实时数据。这种方式没有改变代码执行的顺序,也没有改变异步和同步的方式,只是改变了赋值方式。这种方式在父方法不能为异步方法时,很有效。再次强调,如果为基本类型,包装在一个对象或数组的应用下才有效。
边栏推荐
- Pytorch learning diary (II)
- [ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter :
- Alibaba cloud Hangzhou arm ECS performance evaluation
- m基于matlab的DQPSK调制解调技术的仿真
- [automated testing] - robotframework practice (III) writing test cases
- 爬虫基础—Session和Cookie
- Steam game server configuration selection IP
- Homework
- 1. What is a server?
- SNN learning diary - install spikengjelly
猜你喜欢

Review summary of MySQL

9.账户和权限

Intranet penetration server building tutorial, NPs use tutorial

SNN学习日记——安装SpikingJelly

快速学会cut命令,uniq命令的使用
![[automated testing] - robotframework practice (II) new test cases](/img/e8/b5e945400445c66e3a7a129744c21d.png)
[automated testing] - robotframework practice (II) new test cases

M design of GPS data longitude and latitude height analysis and Kalman analysis software based on matlab-GUI

Servlet 笔记

m基于Simulink的高速跳频通信系统抗干扰性能分析

Alibaba cloud Hangzhou arm ECS performance evaluation
随机推荐
[automated testing] - robotframework practice (III) writing test cases
Évaluation des performances de la machine virtuelle Tianyi Cloud Hangzhou (VPS)
高防服务器是如何确认哪些是恶意IP/流量?ip:103.88.32.XXX
Regular expression, generator, iterator
快速学会cut命令,uniq命令的使用
m基于matlab的DQPSK调制解调技术的仿真
STEAM游戏高主频i9-12900k 搭建CS:GO服务器
华为云 鲲鹏ARM云服务器 和 x86云服务器 性能评测对比
Alibaba cloud Hangzhou arm ECS performance evaluation
ArraysList方法
Closures and decorators
How to record enterprise or personal domain names
天翼雲 杭州 雲主機(VPS) 性能評測
Weight matching (greedy)
The use and differences of dictionaries, tuples and lists,
m基于matlab的超宽带MIMO雷达对目标的检测仿真,考虑时间反转
论文阅读:Deep Residual Shrinkage Networksfor Fault Diagnosis
正则表达式,生成器,迭代器
搭建一个网站都需要那些东西
Matlab implementation code of image denoising method based on Hidden Markov tree model in wavelet domain