ES6精讲10-Generator的应用

171 阅读1分钟

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...页面'); 
}