Promise、Generator函数、yield、async/await 相关html
今有一题,题目为:前端
ajax1()
和ajax2()
,用于快速初始化CODE1和CODE2伪代码为:ajax
Ajax1({ ... success: function(data){ CODE1 = data } }) Ajax1({ ... success: function(data){ CODE1 = data } }) myFunc(CODE1, CODE2)
做为一个后端,我最早想到的是建立一个变量来标志两个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()
执行结果:promise
能够看到myFunc在两个ajax执行完成以后才执行。async
yield关键字是ES6添加的语法,能够在函数执行中交出运行权限函数
上面第一种方法一看就是不会前端的人写的,前端若是要想炫技的话能够这么写:code
//第二种 //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 函数的含义与用法htm
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可是都没介绍,就是想把最合适的一种放到最后:
//第四中,同时也是最优解 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)