用四种方法将两个AJAX改为同步

Promise、Generator函数、yield、async/await 相关


今有一题,题目为:

  1. 现有ajax1()ajax2(),用于快速初始化CODE1和CODE2
  2. myFunc必须在CODE1和CODE2初始化之后再执行
  3. 可以在原代码上修改

伪代码为:

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改为同步的更多相关文章

  1. 两个变量交换的四种方法(Java)

    对于两种变量的交换,我发现四种方法,下面我用Java来演示一下. 1.利用第三个变量交换数值,简单的方法. (代码演示一下) class TestEV //创建一个类 { public static ...

  2. Java中取小数点后两位(四种方法)

    摘自http://irobot.iteye.com/blog/285537 Java中取小数点后两位(四种方法)   一 Long是长整型,怎么有小数,是double吧     java.text.D ...

  3. Android提交数据到服务器的两种方式四种方法

    本帖最后由 yanghe123 于 2012-6-7 09:58 编辑 Android应用开发中,会经常要提交数据到服务器和从服务器得到数据,本文主要是给出了利用http协议采用HttpClient方 ...

  4. 两个变量交换的四种方法(Java) 七种方法(JS)

    两个变量交换的四种方法(Java)   对于两种变量的交换,我发现四种方法,下面我用Java来演示一下. 1.利用第三个变量交换数值,简单的方法. (代码演示一下) 1 class TestEV 2 ...

  5. 关于fmri数据分析的两大类,四种方法

    关于fmri数据分析的两大类,四种方法: 数据驱动: tca:其实这种方法,主要是提取时间维的特征.如果用它来进行数据的分析,则必须要利用其他的数据方法,比如结合ICA. ica:作为pca的一般化实 ...

  6. 织梦DedeCMS模板防盗的四种方法

    织梦(DedeCMS)模板也是一种财富,不想自己辛辛苦苦做的模板被盗用,在互联网上出现一些和自己一模一样的网站,就需要做好模板防盗.本文是No牛收集整理自网络,不过网上的版本都没有提供 Nginx 3 ...

  7. Angular--页面间切换及传值的四种方法

    1. 基于ui-router的页面跳转传参(1) 在AngularJS的app.js中用ui-router定义路由,比如现在有两个页面,一个页面(producers.html)放置了多个produce ...

  8. C#播放声音的四种方法 +AxWindowsMediaPlayer的详细用法

    C#播放声音的四种方法 第一种是利用DirectX 1.安装了DirectX SDK(有9个DLL文件).这里我们只用到MicroSoft.DirectX.dll和 Microsoft.Directx ...

  9. IOS中Json解析的四种方法

    作为一种轻量级的数据交换格式,json正在逐步取代xml,成为网络数据的通用格式. 有的json代码格式比较混乱,可以使用此“http://www.bejson.com/”网站来进行JSON格式化校验 ...

随机推荐

  1. 学习笔记(14)- SQuAD的数据格式

    BERT模型完成问答任务的时候,需要数据格式为SQuAD形式. 有2个版本,1.1和2.0

  2. Android studio For Mac 安装

    简介: Google在2013的I/O开发者大会上正式对外宣布Android Studio将作为Android开发的主要IDE,它是基于IntelliJ IDEA打造的一款专门开发Android的神器 ...

  3. Periodic-table

    1. Periodic table 1.1 元素的排列 1.2 表中的行与列 1.3 元素区块 1.4 周期表中的一些趋势 1.5 元素周期律的本质 1.6 电子排布 2. 更多相关链接 2.1 维基 ...

  4. Codeforces 1260 ABC

    DEF 题对于 wyh 来说过于毒瘤,十分不可做. A. Heating Description: 给定\(a,b\),将\(b\)分成至少\(a\)个正整数,使这些正整数的平方和最小. Soluti ...

  5. 第1节 kafka消息队列:3、4、kafka的安装以及命令行的管理使用

    6.kafka的安装 5.1三台机器安装zookeeper 注意:安装zookeeper之前一定要确保三台机器时钟同步 */1 * * * * /usr/sbin/ntpdate us.pool.nt ...

  6. 一、java基础-数据类型_数据类型转化_字符编码_转义字符

    1.Java  支持的8种基本数据类型: java的四种整数数据类型:byte 1    short 2     int4     long8   byte     8位带符号整数 -128到127之 ...

  7. JS原生编写实现留言板功能

    实现这个留言板功能比较简单,所以先上效果图: 实现用户留言内容,留言具体时间. <script> window.onload = function(){ var oMessageBox = ...

  8. 前端面试题CSS一(题目来源网络)

    一.什么是html5语义化? 使用合理,正确的html标签格式化文档. 二.CSS样式优先级? 就近原则,行内>内联>外联 三 什么是盒模型? 主要分为两种,w3c标准盒模型,IE标准模型 ...

  9. redis、mongodb、memcache安装好后设置开机自启动

    vim /etc/rc.d/rc.local /usr/local/mongodb/bin/mongod --smallfiles /usr/local/bin/redis-server/usr/lo ...

  10. php 实现店铺装修4

    /** * @title 发布装修的店铺 * @example FlagShipShopDecorate.fabu? 调试参数:{"username":"17721355 ...