两个ajax如何实现同步,用四种方法将两个AJAX改为同步

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

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

今有一题,题目为:

现有ajax1()和ajax2(),用于快速初始化CODE1和CODE2

myFunc必须在CODE1和CODE2初始化之后再执行

可以在原代码上修改

伪代码为:

Ajax1({

...

success: function(data){

CODE1 = data

}

})

Ajax1({

...

success: function(data){

CODE1 = 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)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值