用四种方法将两个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格式化校验 ...
随机推荐
- 搭建私有CA并实现证书颁发
一.搭建私有CA服务器 1.安装包 # yum -y install openssl 2.生成密钥对儿 # cd /etc/pki/CA # (umask 077;openssl genrsa -ou ...
- Android编程实现点击链接打开APP功能示例
本文实例讲述了Android编程实现点击链接打开APP功能.分享给大家供大家参考,具体如下: 在Android中点击链接打开APP是一个很常见的需求.例如,电商为用户发送优惠券之后经常会下发一条短信: ...
- jsp页面 将数据以Json 格式保存到数据库
1:jsp页面 <div class="control-group form-group all_activity"> <c:choose> <c:w ...
- jsp页面展示更加商品的分类,控制商品的显示
我的大概思路是这样的,第一后果获取所有的商品分类 保存在list集合里面,第二从后台获取所有的商品 第三在JSP页面遍历商品分类集合放在页面的左边,然后jsp页面商品详细信息这块,也得先遍历商品分类, ...
- 把链接生成二维码 二维码中间带有logo
在工程中引入三个文件jquery.qrcode.js.qrcode.js.utf.js.其中utf.js文件是防止链接中的参数出现中文乱码现象 jquery.qrcode.js文件 function ...
- 9.2.3 hadoop reduce端连接-分区分组聚合
1.1.1 reduce端连接-分区分组聚合 reduce端连接则是利用了reduce的分区功能将stationid相同的分到同一个分区,在利用reduce的分组聚合功能,将同一个st ...
- 本周总结(19年暑假)—— Part7
日期:2019.8.25 博客期:113 星期日
- [Linux] day07——查看及过滤文本
查看及过滤文本 =====================================cat concatenate -n 添加行号------------------- ...
- 《React后台管理系统实战 零》:基础笔记
day01 1. 项目开发准备 1). 描述项目 2). 技术选型 3). API接口/接口文档/测试接口 2. 启动项目开发 1). 使用react脚手架创建项目 2). 开发环境运行: npm s ...
- C# 增加时间的三个方法
第一个是使用方法形式的实例方法: incrementer.CountedADozen += IncrementDozensCount; //方法引用形式 第二个是使用方法形式的静态方法: incre ...