ES6 Generator和Promise

目录

Generator

[如何创建Generator函数 ?](#如何创建Generator函数 ?)

模拟发起异步请求

Promise

实例化

实例方法

工厂函数

静态方法

Promise.all([p1,p2,....])

Promise.race([p1,p2,....])

Promise.any([p1,p2,....])

Promise.allSettled([p1,p2,....])


Generator

Generator是ES6提供的一种异步编程解决方案,语法不同于普通函数;简单的把Generator 理解为一个状态机,封装了多个内部状态。执行Generator 函数会返回一个迭代器对象,可以通过调用迭代器next依次遍历Generator函数内部的每一个状态。

如何创建Generator函数 ?

每个状态之间都是独立的

javascript 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        /**
         * generator 函数 也是一种异步编程的解决方案 理解为状态机 内部封装多个状态
         * 调用generator 函数返回值是迭代器对象 每调用一次迭代器next方法 就会执行一个状态
         * 特征:
         *  1.function 和函数名之间使用*  靠前靠后不靠都可以
         *  2.返回一个迭代器对象   并且内部状态使用yiled表达式
         * 
         * generator函数内部使用yield表达式 一个yield就是一个状态 一个yield就是一个代码节点通过迭代器对象的next方法控制的代码的向下执行。
        */
        function * generator(){
            yield '1';
            yield '2';
            yield '3';
        }
        let res = generator();
        console.log(res.next());
        for(let key of res){
            console.log(key);
        }
    </script>
</body>
</html>

因为return会阻止后面的代码运行,所以 Generator提供了yield,yiled也是返回值,但是执行一次状态停在了第一个yield ,依次执行next方法,执行下一个yield状态。代码分段执行,一个yield分一段。上一个yield结束是下个状态的开始,下一个状态的结束再执行下一个yield。yield后面的是返回值。最后一个yield可以return返回。

模拟发起异步请求

拿到第一个状态的返回结果再执行第二个状态,状态之间数据传递通过next

javascript 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        /**
         * 想要在第二个状态执行的时候调用第一个状态的返回值 
         * 一个yield就是一个状态 一个yield就是一个代码运行节点 
         * 迭代器对象每次调用next只会执行一个状态
         * 迭代器对象调用next方法 执行第一个状态产生返回值 在第二个状态中是接收不到 
         * 可以在第二个状态中传递参数 返回值接收的就是什么参数 
        */
        function* generator(){
            // 发送一个请求 
            log();
            let res = yield '1';
            console.log(res,'第一个状态返回值');
            yield '2';
        }
        let res = generator();
        // 发起第一个状态的执行
        res.next();
        // 发起第二个状态的执行
        // 如果想要在第二个状态中获取第一个状态返回值 需要在第二段状态执行的时候传递参数
        res.next(100);
        // 模拟异步请求
        function log(){
           for(let i=0;i<=10;i++){
             console.log(i)
           }
        }
    </script>
</body>
</html>

如果想要实现数据传递 需要发起第二段程序执行 拿上一个状态得返回值作为下一个状态得入口

javascript 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/1.3.6/axios.js"></script>
</head>
<body>
    <script>
        function *generator(){
            // 每一个代码节点发起异步请求 
            let res = yield getData();
            console.log(res,'第一个异步请求的返回值');
            yield '结束了';
        }
        let res = generator();
        res.next();
        
        // 封装一个异步函数
        async function getData(){
            let result = await axios.get('http://121.199.0.35:8888/index/carousel/findAll');
            // result 异步请求的返回值 后端返回的数据 result.data
            console.log(result,'响应数据');
            // 在第一个状态的异步函数中发起第二段状态执行 并且把第一个状态产生返回值当做下一个状态的入口
            res.next(result.data);
        }
    </script>
</body>
</html>

Promise

Promise是一种异步编程解决方案,Promise是一个容器,保存着将来才会执行的代码;从语法角度来说Promise是一个对象,可以用来获取异步操作的消息。异步操作,同步解决,避免了层层嵌套的回调函数,可以链式调用降低了操作难度。

实例化

Promise构造函数接收一个函数作为参数,也就是回调函数;

该函数的两个参数分别是resolve和reject。resolve作为成功的回调函数,reject作为失败的回调函数。

Promise对象代表一个异步操作有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。最后返回resolved(已定型)结果。

实例方法

定义在Promise.prototype中的方法,通过Promise实例可以直接调用

then(res=>{}) 状态由pending变为fulfilled的时候也就是异步操作成功之后执行该回调函数

参数:回调函数,回调函数的参数为resolve函数传递过来的值

返回值:返回一个新的Promise实例对象,因此可以使用链式调用

catch(err=>{}) 由pending变为rejected的时候执行该回调函数也就是异步失败之后执行该回调函数

参数:回调函数,回调函数的参数为reject函数传递过来的值

返回值:返回一个新的Promise实例对象,因此可以使用链式调用

finally()无论异步操作执行成功失败与否,都会执行该回调

参数:回调函数

返回值:返回一个新的Promise实例对象

javascript 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=s, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 创建promise实例对象 参数 回调函数
        let promise = new Promise((resolve,reject)=>{
            /**
             * resolve 是成功的回调函数
             * reject 是失败的回调函数
             * 不发送请求 此时promise实例状态pending进行中
            */
            // 模拟发送异步请求
            if(3<2){
                // let res = await axios.get();
                resolve('发送成功');
            }else{
                reject('发送失败')
            }
        });
        // console.log(promise);
        /**
         * promise实例状态为fullfilled走then回调
         * promise实例状态为rejected走catch回调
        */
        promise.then((res)=>{
            console.log(res);
        }).catch((error)=>{
            console.log(error);
        }).finally(()=>{
            console.log('最终状态');
        })
        /**
         * then方法提供了两个回调函数 
         * 第一个回调函数是成功的回调 第二个回调函数是失败的回调 
         * resolve reject
        */
        promise.then((res)=>{
            console.log(res);
        },(error)=>{
            console.log(error);
        })
    </script>
</body>
</html>

考虑到需要创建多个promise实例对象 这些对象封装ajax请求

使用工厂函数创建promise实例对象

工厂函数

在下面静态方法的代码中

静态方法

Promise.all([p1,p2,....])

参数:数组 [多个promise实例] 返回值:promise实例 实例状态

每一个请求实例为fullfilled,才是fullfilled。否则是rejected

Promise.race([p1,p2,....])

参数:数组 [多个promise实例] 返回值:返回先请求成功的实例 返回的也是promise实例对象

Promise.any([p1,p2,....])

参数:数组 [多个promise实例] 返回值:返回任意一个成功的实例

Promise.allSettled([p1,p2,....])

参数:数组 [多个promise实例] 返回值:promise实例

每一个请求实例为rejected,才是rejected。否则是fullfilled

javascript 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        function promise(method, url) {
            return new Promise((resolve, reject) => {
                // 创建一个请求实例
                let xhr = new XMLHttpRequest();
                // 打开链接
                xhr.open(method, url);
                // 发送请求
                xhr.send();
                // 接收响应
                xhr.onreadystatechange = function () {
                    if (xhr.readyState === 4) {
                        if (xhr.status === 200) {
                            resolve(JSON.parse(xhr.response));
                        } else {
                            reject('接收失败');
                        }
                    }
                }
            });
        }
        let p1 = promise('get', 'http://121.199.0.35:8888/index/category/findAll');
        let p2 = promise('get', 'http://121.199.0.35:8887/index/carousel/findAll');
        // p1.then((res) => {
        //     console.log(res, 'res接收成功');
        // }).catch((error) => {
        //     console.log(error, '出现错误');
        // })
        // p2.then((res) => {
        //     console.log(res, 'res接收成功');
        // }).catch((error) => {
        //     console.log(error, '出现错误');
        // })

        // 静态方法 同时发送多个请求
        // Promise.all([p1,p2,....]) 参数:数组 [多个promise实例] 返回值:promise实例 实例状态
        // 每一个请求实例为fullfilled,才是fullfilled。否则是rejected
        let res = Promise.all([p1,p2]);
        // Promise.race([p1,p2,....])   参数:数组 [多个promise实例] 返回值:返回先请求成功的实例 返回的也是promise实例对象
        // let res = Promise.race([p1,p2]);
        // Promise.any([p1,p2,....])  参数:数组 [多个promise实例] 返回值:返回任意一个成功的实例
        // let res = Promise.any([p1,p2]);
        // Promise.allSettled([p1,p2,....]) 参数:数组 [多个promise实例] 返回值:promise实例
        // 每一个请求实例为rejected,才是rejected。否则是fullfilled
        // let res = Promise.allSettled([p1,p2])
        console.log(res);       //promise实例 实例状态 
        res.then((res)=>{
            console.log(res,'all方法res接收的是数组');
        }).catch((error)=>{
            console.log(error);
        })
    </script>
</body>

</html>
相关推荐
崔庆才丨静觅4 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60614 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了5 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅5 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅5 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅5 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment5 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅6 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊6 小时前
jwt介绍
前端
爱敲代码的小鱼6 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax