ES6 Generator和Promise

news2024/11/22 17:15:21

目录

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函数 ?

每个状态之间都是独立的

<!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

<!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>

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

<!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实例对象

<!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

<!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>

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/766737.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Day56|583. 两个字符串的删除操作 、72. 编辑距离

583. 两个字符串的删除操作 1.题目&#xff1a; 给定两个单词 word1 和 word2 &#xff0c;返回使得 word1 和 word2 相同所需的最小步数。 每步 可以删除任意一个字符串中的一个字符。 示例 1&#xff1a; 输入: word1 "sea", word2 "eat" 输出: …

SSD 常用概念

1. 写入放大&#xff08;WA&#xff09; 写入放大会对闪存 P / E 次数造成磨损。在存储过程中&#xff0c;数据会在闪存上被反复的移动整理&#xff0c;造成闪存上的写入量大于实际文件写入量&#xff0c;这个过程称为写放大。 写放大 主控实际写入的数据量 / 用户想要写入的数…

GDB调试——学习笔记

文章目录 GDB是什么GDB调试的一般步骤1. 编译生成带源代码信息的可执行文件2. 启动调试3. 进行调试&#xff1a;设置断点、查看变量、寻找BUG4. 退出调试 GDB是什么 GDB就是一个程序代码调试的工具。 GDBGCC开发环境 GDB调试的一般步骤 1. 编译生成带源代码信息的可执行文件…

机器学习1

核心梯度下降算法&#xff1a; import numpy as np from utils.features import prepare_for_trainingclass LinearRegression:def __init__(self,data,labels,polynomial_degree 0,sinusoid_degree 0,normalize_dataTrue):"""1.对数据进行预处理操作2.先得到…

【Linux】进程信号 -- 信号产生 | 系统调用、硬件、软件的信号发送

信号的旧识引入信号引入signal调用 系统调用向目标进程发送信号模拟实现一个kill命令raise给自己发送任意信号abort给自己发送指定信号(6)SIGABRT 硬件异常产生信号除0异常野指针访问异常 软件条件产生信号拓展 总结思考进程退出时核心转储问题小实验 信号的旧识引入 kill -l是…

手动实现 Tomcat 底层机制+ 自己设Servlet 问题分析

文章目录 手动实现 Tomcat 底层机制 自己设Servlet问题分析完成小案例运行效果 此项目用maven至于怎么配置在下一篇文章创建cal.htmlCalServlet.java# 实现步骤 web.xmlWebUtils 问题:Tomcat 整体架构分析测试分析&#xff1a;抓包情况 手动实现 Tomcat 底层机制 自己设Servlet…

ALPAGASUS : TRAINING A BETTER ALPACA WITH FEWER DATA♢

ALPAGASUS : TRAINING A BETTER ALPACA WITH FEWER DATA♢ IntroductionMethod参考 Introduction 本文证明了数据的质量的重要性要大于数量。作者通过与GPT交互的方法过滤了Alpaca52k的数据&#xff0c;剩下9k&#xff0c;对二者分别微调&#xff0c;通过实验对比&#xff0c;…

软件测试行业的困境和迷局

中国的软件测试虽然起点较高&#xff0c;但是软件测试的发展似乎没有想象中那么顺利。 其实每个行业除了有自身领域外&#xff0c;还有属于自己的“生态系统”。属于软件测试的生态系统主要包括后备软件测试人员、软件开发人员和软件管理决策者。后备软件测试人员是软件测试的…

获取gitlab上项目列表过程及脚本

一、使用Gitlab API查询项目列表 1、首先获取访问令牌&#xff1a;在Gitlab上生成一个访问令牌&#xff0c;以便能够使用API进行身份验证。可以在GitLab的用户设置中创建一个访问令牌。 2、使用curl发送GET请求的命令&#xff1a; curl --header "PRIVATE-TOKEN: <you…

若依字典使用

若依字典使用 此文章使用的若依是大于3.7.0版本的 JS文件配置 main.js中引入全局变量和方法 import DictData from /components/DictData DictData.install()DictData.js配置 可以从DictData.js中看出在install方法中调用了字典查询接口&#xff0c;在install方法中可以做…

Atom配置Java开发环境

第1步&#xff1a; 从Oracle网站下载安装最新的Java开发包&#xff08;JDK&#xff09; 将JDK添加到环境变量中 参考链接&#xff1a;传送门1&#xff08;外网&#xff09;&#xff0c; 传送门2&#xff08;国内&#xff09; 第2步&#xff1a;现在要在Atom编辑器上运行Jav…

【C++修炼之路】list 模拟实现

&#x1f451;作者主页&#xff1a;安 度 因 &#x1f3e0;学习社区&#xff1a;StackFrame &#x1f4d6;专栏链接&#xff1a;C修炼之路 文章目录 一、读源码二、成员三、默认成员函数1、构造2、析构3、拷贝构造4、赋值重载 四、迭代器五、其他接口 如果无聊的话&#xff0c;…

Pytorch自动求导机制详解

目录 1. 自动求导 1.1 梯度计算 1.1.1 一阶导数 1.1.2 二阶导数 1.1.3 向量 1.2 线性回归实战 1. 自动求导 在深度学习中&#xff0c;我们通常需要训练一个模型来最小化损失函数。这个过程可以通过梯度下降等优化算法来实现。梯度是函数在某一点上的变化率&#xff0c;可以告…

vue代码格式化,Prettier - Code formatter格式化规则文件

vue2&#xff0c;vue3格式化代码使用方法&#xff1a; 1、新建文件名&#xff1a; .prettierrc.cjs&#xff0c;里面放上下面的代码片段&#xff0c;直接粘贴即可 2、把 .prettierrc.cjs文件放在项目的根目录中 // prettier的默认配置文件 module.exports {// 一行最多 100 …

Final Cut Pro中文新手教程 (52绿幕抠图)FCPX透明通道基础使用方法

今天小编为大家分享的是FCPX透明通道基础教程&#xff0c;究竟什么是透明通道呢&#xff1f;透明通道就是一个阿尔法(alpha)通道&#xff0c;也叫做通明阿尔法通道。只要带有alpha的图片或者视频&#xff0c;他们的背景就是透明的只会显示他们的形状和内容。这种技术经常应用在…

VLAN :虚拟局域网

目录 VLAN&#xff1a;虚拟局域网 VLAN种类&#xff1a; 接口分配链路类型 接口划分VLAN 跨网段的通讯 VLAN&#xff1a;虚拟局域网 LAN &#xff1a;局域网 MAN&#xff1a;城域网 WAN&#xff1a;广域网 1.一个VLAN相当于一个广播域 VLAN&#xff1a;通过路由器和交换机…

OpenCv之图像形态学

目录 一、形态学 二、图像全局二值化 三、自适应阈值二值化 四、腐蚀操作 五、获取形态学卷积核 六、膨胀操作 七、开运算 八、闭运算 一、形态学 定义: 指一系列处理图像形状特征的图像处理技术形态学的基本思想是利用一种特殊的结构元(本质上就是卷积核)来测量或提取输…

数据结构--图的基本操作

数据结构–图的基本操作 使用的存储模式&#xff1a; 图的基本操作&#xff1a; • Adjacent(G,x,y)&#xff1a;判断图G是否存在边<x, y>或(x, y)。 • Neighbors(G,x)&#xff1a;列出图G中与结点x邻接的边。 • InsertVertex(G,x)&#xff1a;在图G中插入顶点x。 • …

VSCode 注释后光标快速定位下一行

VSCode默认用 Ctrl / 注释一行时&#xff0c;光标停留在该行中。下面介绍如何注释后&#xff0c;光标会自动移动到下一行。 1.【View】 ->【Extensions】->【查找并安装Multi-command 扩展】 2.【File 】 -> 【Preferences 】->【Keyboard Shortcuts】&#xff08…

怎样优雅地增删查改(八):按用户关系查询

文章目录 原理实现正向用户关系反向用户关系 使用测试 用户关系&#xff08;Relation&#xff09;是描述业务系统中人员与人员之间的关系&#xff0c;如&#xff1a;签约、关注&#xff0c;或者朋友关系。 之前我们在扩展身份管理模块的时候&#xff0c;已经实现了用户关系管理…