1.首先就是来回顾下历史,老生常谈的回调地狱问题
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>11 Generator的应用</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<script>
// Generator 部署ajax操作,让异步代码同步化
// 回调地狱
$.ajax({
url: 'https://free-api.heweather.net/s6/weather/now?location=beijing&key=4693ff5ea653469f8bb0c29638035976',
method: 'get',
success(res) {
console.log(res);
// 继续发送请求
$.ajax({
url: '',
method: 'get',
success(res1) {
// 发送ajax
$.ajax({
url: '',
method: 'get',
success(res2) {
// 发送ajax
$
}
})
}
})
}
})
</script>
</body>
</html>
- 这样只要外层请求一改动,内部的所有业务逻辑都需要做出改动,而且这个嵌套...
2.Generator 部署ajax操作,让异步代码同步化
异步代码同步化具体实现思路:
- 首先定义一个generator函数,内部编写发送请求的代码
- 外部声明一个变量(这里是ite)去接收main函数第一次调用后返回的迭代器
- 定义后第一次ite.next(),是去执行yield的请求,这里需要主要的就是,如果第二次next没有被调用,那么只到执行了发送请求后这一步就结束了(这里并没有对main函数中的res赋值),函数也不会往下执行下面的代码
- 在reauest中第二次调用next,并将请求结果作为参数传入,这样main函数中的res就被赋值为res了,函数继续往下走,执行下面的代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>11 Generator的应用</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<script>
function* main() {
console.log('main');
let res = yield request(
'https://free-api.heweather.net/s6/weather/now?location=beijing&key=4693ff5ea653469f8bb0c29638035976'
)
//🌵 执行后面的操作(这里是第二次next执行之后才会执行的)
console.log(res); // 🌵{HeWeather6: Array(1)}
console.log('数据请求完成,可以继续操作');
}
const ite = main(); //①:返回一个迭代器
ite.next(); //②:执行yield后面的请求(注意,对res的赋值是下一次next做的事情)
function request(url) {
$.ajax({
url,
method: 'get',
success(res) {
ite.next(res); //③:将res结果next出去,赋值给上面main函数中的res
}
})
}
</script>
</body>
</html>
3.加载loading页面例子
这里就不在多做详细的解释了,基本思路和上面一致
function* load() {
loadUI();
yield showData();
hideUI();
}
let itLoad = load();
itLoad.next();
function loadUI() {
console.log('加载loading...页面');
}
function showData() {
// 模拟异步操作
setTimeout(() => {
console.log('数据加载完成');
itLoad.next();
}, 1000);
}
function hideUI() {
console.log('隐藏loading...页面');
}