用四种方法将两个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格式化校验 ...
随机推荐
- ES5 Object.assign 低版本浏览器内核兼容问题
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { ...
- 图片的onload事件与better-scroll结合[ 当fastclick插件和better-scroll发生冲突导致点击事件失效时,可以给需要点击的元素加一个class="needsclick"]
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Lamda表达式学习笔记二
Lamda表达式学习笔记二 lamda表达式----方法引用 上一篇讲到Lamda体就是对函数式接口方法的实现 ,在方法体中我们可能会引用其他方法实现逻辑,所以在lamda体中我们可以直接引用器方法 ...
- Java 在Excel单元格中应用一种/多种字体样式
在Excel表格中,设置单元格字体样式时,可以对单元格内的所有字符应用同一样式,即获取指定单元,应用样式即可:另外也可以对单元格内的不同字符内容应用不同字体样式,即获取单元格中的字符位置,应用样式:本 ...
- 如何用python写个人专属群聊提醒小助手?
前言 大家还记得教会父母玩微信是什么时候吗?父母学会后,我们的生活就发生了「质」的变化,父母也许会吐槽你的微信头像不好,要你换一个头像. 最近 pk哥 又被母后大人吐槽了,原因是亲戚微信群里某个亲戚生 ...
- 一 Java语言基础
1 标识符: 用来标识类名.变量名.方法名.类型名.数组名.文件名的有效字符序列. 由字母.美元符.下划线.数字组成,不能以数字开头,如 int 6a = 1; 2 基本数据类型8个: 整数4个:字 ...
- 【剑指Offer面试编程题】题目1505:两个链表的第一个公共结点--九度OJ
题目描述: 输入两个链表,找出它们的第一个公共结点. 输入: 输入可能包含多个测试样例. 对于每个测试案例,输入的第一行为两个整数m和n(1<=m,n<=1000):代表将要输入的两个链表 ...
- phpQuery的使用
前言 为什么使用phpQuery phpQuery是基于php5新添加的DOMDocument.而DOMDocument则是专门用来处理html/xml.它提供了强大的xpath选择器及其他很多htm ...
- 学习打卡8:循环语句for、while
流程图: /*循环结构的基本组成部分,一般可以分成四部分:1.初始化语句:在循环开始最初执行,而且只做唯一一次.2.条件判断:如果成立,则循环继续:如果不成立,则循环退出.3.循环体:重复要做的内容, ...
- Qt中QListWidget的verticalScrollMode选项设置为ScrollPerPixel无效果的原因
设置为ScrollPerPixel无效果,根据Qt手册的描述,需要在设置一次setSingleStep()的值,才会生效