用四种方法将两个AJAX改为同步
用四种方法将两个AJAX改为同步
Promise、Generator函数、yield、async/await 相关
今有一题,题目为:
- 现有
ajax1()和ajax2(),用于快速初始化CODE1和CODE2 - myFunc必须在CODE1和CODE2初始化之后再执行
- 可以在原代码上修改
伪代码为:
Ajax1({
...
success: function(data){
CODE1 = data
}
})
Ajax2({
...
success: function(data){
CODE2 = data
}
})
myFunc(CODE1, CODE2)
立Flag判断
作为一个后端,我最先想到的是创建一个变量来标志两个ajax是否完成,然后再两个ajax的回调中进行判断(至于两个ajax都改为同步这种方法直接不考虑),大致代码如下:
使用了setTimeOut来模拟ajax:
let CODE1 = null
let CODE2 = null
function myFunc() {
console.log(CODE1, CODE2);
}
//第一种
let flag = 0 //flag默认为0
function ajax1() {
setTimeout(() => {
console.log('ajax1得到响应')
CODE1 = 'ajax1返回的数据'
//如果回调时flag为1,代表另一个ajax已经初始化成功
if (flag === 1) {
myFunc()
} else {
//否则flag+1代表本ajax成功
flag += 1
}
}, 1000)
}
function ajax2() {
setTimeout(() => {
console.log('ajax2得到响应')
CODE2 = 'ajax2返回的数据'
if (flag === 1) {
myFunc()
} else {
flag += 1
}
}, 2000)
}
ajax1()
ajax2()
执行结果:

可以看到myFunc在两个ajax执行完成之后才执行。
yield关键字
yield关键字是ES6添加的语法,可以在函数执行中交出运行权限
上面第一种方法一看就是不会前端的人写的,前端如果要想炫技的话可以这么写:
//第二种
//Promise执行器
function run(gen) {
gen = gen()
return next(gen.next())
function next({ done, value }) {
return new Promise(resolve => {
if (done) {
resolve(value)
} else {
value.then(data => {
next(gen.next(data)).then(resolve)
})
}
})
}
}
function ajax1() {
return new Promise(resolve => {
setTimeout(() => {
console.log('ajax1得到响应');
CODE1 = 'ajax1返回的数据'
resolve()
}, 5000)
})
}
function ajax2() {
return new Promise(resolve => {
setTimeout(() => {
console.log('ajax2得到响应');
CODE2 = 'ajax2返回的数据'
resolve()
}, 5000)
})
}
function* call() {
let aj1 = ajax1()
let aj2 = ajax2()
yield aj1
yield aj2
}
run(call).then(myFunc)
什么意思我解释不清楚,也不想解释,自己去看阮一峰的博客:Generator 函数的含义与用法
async/await关键字
async/await关键字是ES7的语法,是对上面Promise执行器的一种简化:
// 第三种
function ajax1() {
return new Promise(resolve => {
setTimeout(() => {
console.log('ajax1得到响应');
CODE1 = 'ajax1返回的数据'
resolve()
}, 1000)
})
}
function ajax2() {
return new Promise(resolve => {
setTimeout(() => {
console.log('ajax2得到响应');
CODE2 = 'ajax2返回的数据'
resolve()
}, 2000)
})
}
async function call() {
/*
这里不能这么写:
await ajax1()
await ajax2()
这样会在ajax1之后才会执行ajax2
需要写成下面的这种:
*/
let aj1 = ajax1()
let aj2 = ajax2()
await aj1
await aj2
myFunc()
}
call()
async声明这是一个内部存在同步的函数,只有声明了async,函数内部才能使用await,await代表等待Promise执行完毕才会继续执行,的确有点同步的感觉了。
Promise
上面用到了Promise但是都没介绍,就是想把最合适的一种放到最后:
//第四中,同时也是最优解
function ajax1(resolve, reject) {
setTimeout(()=>{
console.log('ajax1得到响应');
CODE1 = 'ajax1返回的数据'
resolve()
},1000)
}
function ajax2(resolve, reject) {
setTimeout(()=>{
console.log('ajax2得到响应');
CODE2 = 'ajax2返回的数据'
resolve()
},2000)
}
const p1 = new Promise(ajax1)
const p2 = new Promise(ajax2)
Promise.all([p1, p2]).then(myFunc)
函数Promise.all()接收一个Promise数组参数,作用是数组内的Promise执行完毕之后会返回一个Promise对象。(还有一个Promise.race()方法也挺好玩,作用是参数中任意一个Promise完成就返回一个Promise)
用四种方法将两个AJAX改为同步的更多相关文章
- 两个变量交换的四种方法(Java)
对于两种变量的交换,我发现四种方法,下面我用Java来演示一下. 1.利用第三个变量交换数值,简单的方法. (代码演示一下) class TestEV //创建一个类 { public static ...
- Java中取小数点后两位(四种方法)
摘自http://irobot.iteye.com/blog/285537 Java中取小数点后两位(四种方法) 一 Long是长整型,怎么有小数,是double吧 java.text.D ...
- Android提交数据到服务器的两种方式四种方法
本帖最后由 yanghe123 于 2012-6-7 09:58 编辑 Android应用开发中,会经常要提交数据到服务器和从服务器得到数据,本文主要是给出了利用http协议采用HttpClient方 ...
- 两个变量交换的四种方法(Java) 七种方法(JS)
两个变量交换的四种方法(Java) 对于两种变量的交换,我发现四种方法,下面我用Java来演示一下. 1.利用第三个变量交换数值,简单的方法. (代码演示一下) 1 class TestEV 2 ...
- 关于fmri数据分析的两大类,四种方法
关于fmri数据分析的两大类,四种方法: 数据驱动: tca:其实这种方法,主要是提取时间维的特征.如果用它来进行数据的分析,则必须要利用其他的数据方法,比如结合ICA. ica:作为pca的一般化实 ...
- 织梦DedeCMS模板防盗的四种方法
织梦(DedeCMS)模板也是一种财富,不想自己辛辛苦苦做的模板被盗用,在互联网上出现一些和自己一模一样的网站,就需要做好模板防盗.本文是No牛收集整理自网络,不过网上的版本都没有提供 Nginx 3 ...
- Angular--页面间切换及传值的四种方法
1. 基于ui-router的页面跳转传参(1) 在AngularJS的app.js中用ui-router定义路由,比如现在有两个页面,一个页面(producers.html)放置了多个produce ...
- C#播放声音的四种方法 +AxWindowsMediaPlayer的详细用法
C#播放声音的四种方法 第一种是利用DirectX 1.安装了DirectX SDK(有9个DLL文件).这里我们只用到MicroSoft.DirectX.dll和 Microsoft.Directx ...
- IOS中Json解析的四种方法
作为一种轻量级的数据交换格式,json正在逐步取代xml,成为网络数据的通用格式. 有的json代码格式比较混乱,可以使用此“http://www.bejson.com/”网站来进行JSON格式化校验 ...
随机推荐
- checkbox 选中获取值
1:jsp 页面 从页面获取checkbox 的值传到后台 <div id="divCheckbox" class="hide"> <tr&g ...
- StringUtils工具类中的isBlank()方法和isEmpty()方法的区别
1.isBlank()方法 1 public static boolean isBlank(String str) { 2 int strLen; 3 if (str == null || (strL ...
- Linux CentOS7 VMware 安装PHP5 、安装PHP7
一.安装PHP5 PHP官网www.php.net 当前主流版本为5.6/7.1 cd /usr/local/src/ wget http://cn2.php.net/distributions/ph ...
- C语言笔记 14_标准库&assert&ctype&errno&float&limits
C 标准库 <assert.h> 简介 C 标准库的 assert.h头文件提供了一个名为 assert 的宏,它可用于验证程序做出的假设,并在假设为假时输出诊断消息. 已定义的宏 ass ...
- C/C++网络编程2——socket函数
本节主要介绍创建套接字的socket函数. #include <sys/socket.h> int socket(int domain, int type, int protocol); ...
- 网易云信-新增自定义消息(iOS版)
https://www.jianshu.com/p/2bfb1c4e9f21 前言 公司业务需要,PC端,移动端都用到了第三方 网易云信 IM来实现在线客服咨询.在这当中难免遇到一些需求是网易云信没有 ...
- 自定义Model类
声明文件 #import <Foundation/Foundation.h> @interface OrderRecordModel : NSObject @property (nonat ...
- mongoDB 分片集群常用指令
1.帮助指令:sh.help(),查看有哪些指令及其含义和使用方法. mongos> sh.help() sh.addShard( host ) se ...
- Linux centos7日常运维——监控io性能、free内存命令、ps进程命令、查看网络状态、linux下抓包
一.监控io性能 Linux系统出现了性能问题,一般我们可以通过top.iostat.free.vmstat等命令来查看初步定位问题.其中iostat可以给我们提供丰富的IO状态数据. iostat ...
- 0. GC 前置知识
阅读<垃圾回收的算法与实现>时记录的一些笔记. 对象 在GC的世界中,对象表示的是"通过应用程序利用的数据的集合" 头 我们将对象中保存对象本身信息的部分称为头.头主要 ...