原贴链接:javascript异步之async(二)
这是javascript异步系列文章的第八篇
昨天讨论了javascript的Generator生成器
简单回顾
Generator生成器,区别于普通函数,它可以执行暂停操作,
而next就是驱动Generator的暂停和启动的“开关”
yield只能写在Generator内部,通过next启动生成器后,遇到yield就会暂停
yield和next之间可以相互传值
第一个next不需要传值,第一个next只是用来启动Generator
但是它可以接受第一个yield后面的值(前提是如果有值存在,否则就是undefined)
昨天的栗子🌰有点“hello world”,今天增加一点复杂度
一个需求
需求如下:
现在有接口1,接口2,接口3 按顺序输出接口1,接口2,接口3的请求值
我们还是使用Jquery处理ajax请求
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
还是easy-mock上面的那三个接口,为了拉长接口三的执行时间,我这接口了加入了长度为10-20 的数组 保证它比接口一和接口二慢
因为后面要对这三个接口的请求进行封装,先把代码列出来,方便查询参考
function loadData1() {
$.ajax({
url: "https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/promise1",
success: ({
data,
success
}) => {
if (success) {
console.log(data);
}
}
});
}
function loadData2() {
$.ajax({
url: "https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/promise2",
success: ({
data
}) => {
console.log(data);
}
});
}
function loadData3() {
$.ajax({
url: "https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/mock",
success: ({
data,
success
}) => {
if (success) {
console.log(data);
}
}
});
}
回调函数
常规做法
即,loadData1执行成功后,执行loadData2,loadData2执行成功后执行loadData3
function getData() {
$.ajax({
url: "https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/promise1",
success: ({
data,
success
}) => {
if (success) {
console.log(data);
$.ajax({
url: "https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/promise2",
success: ({
data
}) => {
console.log(data);
if (data.name) {
$.ajax({
url: "https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/mock",
success: ({
data,
success
}) => {
if (success) {
console.log(data);
}
}
});
}
}
});
}
}
});
}
getData()
输出符合预期
回调地狱,说的就是你😂
Promise
来一个Promise实现的,顺便对前面的Promise进行复习
/*
*对ajax的请求做了一个简单的封装
*@ajaxUrl,接口地址,公共部分已经抽取
*@successCb,ajax请求成功后的回调函数
*/
function ajaxFun(ajaxUrl, successCb) {
$.ajax({
url: `https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/${ajaxUrl}`,
success: res => successCb(res)
});
}
//promise
new Promise((resolve, reject) => {
ajaxFun("promise1", ({
data,
success
}) => {
if (success) {
console.log('接口一', data);
resolve(data)
}
})
})
.then(() => {
ajaxFun("promise2", ({
data
}) => {
if (data.name) {
console.log('接口二', data);
}
})
})
.then(() => {
ajaxFun("mock", ({
data,
success
}) => {
if (success) {
console.log('接口三', data);
}
})
})
Generator实现
function loadData1() {
ajaxFun("promise1", ({
data,
success
}) => {
if (success) {
console.log('接口一', data);
it.next()//“接口一成功返回后,执行下一步”
}
})
}
function loadData2() {
ajaxFun("promise2", ({
data
}) => {
if (data.name) {
console.log('接口二', data);
it.next()//“接口二成功返回后,执行下一步”
}
})
}
function loadData3() {
ajaxFun("mock", ({
data,
success
}) => {
if (success) {
console.log('接口三', data);
}
})
}
function* getData() {
yield loadData1()
yield loadData2()
yield loadData3()
}
const it = getData()
it.next()//“启动生成器”
先弄一个遍历器出来,然后通过it.next(),启动遍历器
执行第一个接口请求,当第一个接口请求成功了,继续next(),以此类推
我想很少有人会通过Generator实现多个异步同步执行,但是async可以
下次我们尝试用async await 来实现异步请求同步化
END