ES6语法特性(二)迭代器 生成器 Promise介绍

news2025/2/2 12:30:36

迭代器 生成器 Promise介绍

1. 迭代器

  迭代器就是为实现对不同集合进行统一遍历操作的一种机制,只要给需要遍历的数据结构部署Iterator接口,通过调用该接口,或者使用消耗该接口的API实现遍历操作。
  ES6为迭代器引入了一个隐式的标准化接口。Javascript许多内建的数据结构,例如Array、Map、Set、String、TypedArray、函数的 arguments 对象、NodeList 对象都具备 Iterator 接口。
  Iterator接口主要为for of 使用,for of(遍历的是value
) 不同于for in(遍历的是key)

   const arr = [4, 3, 2, 1];
   for (let v of arr) {
        console.log(v);  // 4 3 2 1
    }

在这里插入图片描述
  可以通过在控制台打印一个Array实例,查看其原型上具有一个Symbol.iterator属性(Symbol.iterator其实是Symbol(‘Symbol.iterator’)的简写,属性名是Symbol类型代表着这个属性的唯一以及不可重写覆盖),它就是迭代器函数,执行这个函数,就会返回一个迭代器对象,对象下有一个next()方法。

1.1. next()迭代

  在获得数组最后一位元素的时候,迭代器不会报告done:true,这时候需要再次调用next(),越过数组结尾的值,才能得到完成信号done:true。
通常情况下,在已经迭代完毕的迭代器对象上继续调用next方法会继续返回{value: undefined, done: true}而不会报错。

1.2. 实现自定义遍历的数据

  自定义遍历obj的list数据,而非obj

      const obj = {
        name: 'gg',
        list: ['a', 'b', 'c', 'd', 'e'],
        [Symbol.iterator]() {
          let index = 0;
          return {
            next: () => {
              if (index < this.list.length) {
                const result = { value: this.list[index], done: false };
                index++;
                return result;
              } else return { value: undefined, done: true };
            }
          };
        }
      };
      for (let v of obj) {
        console.log(v);
      }

在这里插入图片描述

2. 生成器

  生成器就是一个特殊的函数,是针对于异步编程一个新的解决方案。function 和函数名之间加个 *
  返回的是一个迭代器对象 可以使用next() 方法调用
  yield 函数代码的分隔符

  function* gen() {
        console.log('1');
        yield 'a'; // 函数代码的分隔符
        console.log('2');
        yield 'b';
        console.log('3');
        yield 'c';
      }
      let iterator = gen(); // 返回的是一个迭代器对象 可以使用next() 方法调用
      iterator.next(); // 1
      iterator.next(); // 2
      iterator.next(); // 3
      console.log(iterator.next());
      console.log(iterator.next());
      console.log(iterator.next());

在这里插入图片描述
  迭代器对象 即可使用for of
  输出的为yield后面的代码

       function* gen() {
        yield 'a'; // 函数代码的分隔符
        yield 'b';
        yield 'c';
      }
      for (let v of gen()) {
        console.log(v); // a b c
      }

在这里插入图片描述

2.1. 生成器传递参数

  next()方法传递的参数将作为上一个yield的返回值

  function* gen(arg) {
        console.log(arg);
        let one = yield 111;
        console.log(one);
        let two = yield 222;
        console.log(two);
        let three = yield 333;
        console.log(three);
      }
      let iterator = gen('AAA');
      console.log(iterator.next());
      console.log(iterator.next('BBB'));
      console.log(iterator.next('CCC'));
      console.log(iterator.next('DDD'));

2.2. 案例

2.2.1. 需求一

  1s后输出111,接着2s后输出222,接着3s后输出333,总耗时 6s
  (1) 传统写法(回调地狱)

       setTimeout(() => {
        console.log(111);
        setTimeout(() => {
          console.log(222);
          setTimeout(() => {
            console.log(333);
          }, 3000);
        }, 2000);
      }, 1000);

  (2) 生成器写法(优雅)

  const one = () => {
        setTimeout(() => {
          console.log(111);
          iterator.next();
        }, 1000);
      };
      const two = () => {
        setTimeout(() => {
          console.log(222);
          iterator.next();
        }, 2000);
      };
      const three = () => {
        setTimeout(() => {
          console.log(333);
          iterator.next();
        }, 3000);
      };
      function* gen() {
        yield one();
        yield two();
        yield three();
      }
      let iterator = gen();
      iterator.next();

2.2.2. 需求二

  通过用户信息返回订单信息返回商品信息s

    const getUser = () => {
        setTimeout(() => {
          let data = 'user';
          iterator.next(data);
        }, 1000);
      };
      const getOrder = () => {
        setTimeout(() => {
          let data = 'order';
          iterator.next(data);
        }, 1000);
      };
      const getGood = () => {
        setTimeout(() => {
          let data = 'good';
          iterator.next(data);
        }, 1000);
      };
      function* gen() {
        let user = yield getUser();
        console.log(user);
        let order = yield getOrder();
        console.log(order);
        let good = yield getGood();
        console.log(good);
      }
      let iterator = gen();
      iterator.next();

3. Promise

  Promise 是ES6引入的异步编程的新解决方案。Promise是一个构造函数,用来封装异步操作,并可以获取成功.then()或失败.catch()的结果。
  .then(a, b)可以有两个参数,a为成功,b为失败;b也可不写,使用.catch()返回错误

    const p = new Promise((resolve, reject) => {
        setTimeout(() => {
          // let data = 'data';
          // resolve(data);
          let err = 'gg';
          if (err) {
            reject(err);
          }
        }, 1000);
      });
      p.then(
        result => {
          console.log(result);
        },
        err => {
          console.error(err);
        }
      ).catch(err => {
        console.error(err);
      });

3.1. 读取单个文件

  (1)node 错误优先机制

const fs = require('fs');
fs.readFile('./1.txt', (err, data) => {
  if (err) throw err;
  console.log(data);
  console.log(data.toString());
});

  (2)使用promise封装,读取不存在的文件,报错

const p = new Promise((resolve, reject) => {
  fs.readFile('./2.txt', (err, data) => {
    if (err) {
      reject(err);
    }
    resolve(data);
  });
});
p.then(data => {
  console.log(data);
}).catch(err => {
  console.error(err);
});

在这里插入图片描述

3.2. Ajax

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      const xhr = new XMLHttpRequest();
      xhr.open('get', 'http://ip-api.com/json/58.23.7.26?lang=zh-CN');
      xhr.send();
      xhr.onreadystatechange = () => {
        if (xhr.readyState === 4) {
          if (xhr.status >= 200 && xhr.status <= 300) {
            console.log(xhr.response);
          } else {
            console.error(xhr.status);
          }
        }
      };
    </script>
  </body>
</html>

3.3. Promise封装

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      const p = new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.open('get', 'http://ip-api.com/json/58.23.7.26?lang=zh-CN');
        xhr.send();
        xhr.onreadystatechange = () => {
          if (xhr.readyState === 4) {
            if (xhr.status >= 200 && xhr.status <= 300) {
              resolve(xhr.response);
            } else {
              reject(xhr.status);
            }
          }
        };
      });
      p.then(data => {
        console.log(data);
      }).catch(err => {
        console.error(err);
      });
    </script>
  </body>
</html>

3.4. then()

  then可以链式调用,解决回调地狱的问题
  如果return一个空或非promise类型的对象,状态为成功,值为return的值(不return则为undefined)

   const p = new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve('ok');
        }, 1000);
      });
      const result = p
        .then(data => {
          console.log(data);
          // 如果return一个空或非promise类型的对象,状态为成功,值为return的值(不return则为undefined)
          // return 123;
        })
        .catch(err => {
          console.error(err);
        });
      console.log(result);

在这里插入图片描述
  return 一个promise对象(对象返回的状态即为then返回值的状态

      const p = new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve('ok');
        }, 1000);
      });
      const result = p
        .then(data => {
          console.log(data);
          // 如果return一个空或非promise类型的对象,状态为成功,值为return的值(不return则为undefined)
          // return 123;
          // return 一个promise对象(对象返回的状态即为then返回值的状态)
          return new Promise((resolve, reject) => {
            resolve('ok');
          });
        })
        .catch(err => {
          console.error(err);
        });
      console.log(result);

3.5. 读取多个文件

 fs.readFile('./1.txt', (err, data1) => {
  fs.readFile('./2.txt', (err, data2) => {
    fs.readFile('./3.txt', (err, data3) => {
      console.log(data1 + data2 + data3);
    });
  });
});

在这里插入图片描述

new Promise((resolve, reject) => {
  fs.readFile('./1.txt', (err, data) => {
    resolve(data.toString());
  });
})
  .then(value => {
    return new Promise((resolve, reject) => {
      fs.readFile('./2.txt', (err, data) => {
        resolve([value, data.toString()]);
      });
    });
  })
  .then(value => {
    return new Promise((resolve, reject) => {
      fs.readFile('./3.txt', (err, data) => {
        value.push(data.toString());
        resolve(value);
      });
    });
  })
  .then(value => {
    console.log(value);
  });

在这里插入图片描述

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

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

相关文章

鸿蒙4.0实战教学—基础ArkTS(简易视频播放器)

构建主界面 主界面由视频轮播模块和多个视频列表模块组成&#xff0c;效果图如图&#xff1a; VideoData.ets中定义的视频轮播图数组SWIPER_VIDEOS和视频列表图片数组HORIZONTAL_VIDEOS。 // VideoData.ets import { HorizontalVideoItem } from ./HorizontalVideoItem; impo…

[RoarCTF 2019]Easy Java(java web)

题目 页面如下 页面长得像sql注入 点击help看一下 这里需要了解java web目录结构 WEB INF:Java的web应用安全目录&#xff1b; 此外如果想在页面访问WEB-INF应用里面的文件&#xff0c;必须要通过web.xml进行相应的映射才能访问&#xff1b; WEB-INF是Java Web应用程序中的一…

Java连接Mysql报错:javax.net.ssl.SSLException: Received fatal alert: internal_error

大致报错日志如下&#xff1a; The last packet successfully received from the server was 11 milliseconds ago. The last packet sent successfully to the server was 10 milliseconds ago.at sun.reflect.GeneratedConstructorAccessor275.newInstance(Unknown Source)…

Collections

Collections Collections四种对集合进行排序的方式 方法名说明public static <T extends Comparable<? super T>> void sort (List<T> list)排序public static void reverse(List<?> list)逆序public static void shuffle(List<?> list)随机…

scanf函数返回值占位符详解,%*,%[]的应用

前言 scanf函数可以说是我们一开始就会接触的函数了&#xff0c;但在最近复习时我又找到而来一些之前不甚了解或是块要遗忘的知识&#xff0c;特作此篇。 一.返回值 我们之前提到了scanf返回值被忽略的问题&#xff1a; scanf函数返回值被忽略-CSDN博客 那么scanf的返回值…

Unity JSON编码解码之LitJson 深度剖析

把LitJson的代码库放入到项目中&#xff0c;如图所示:JSON在游戏开发中是一种序列化/反序列化常用的技术&#xff0c;把游戏相关的数据,如地图组成,通过JSON编码&#xff0c;序列化成JSON文本&#xff0c;传输或存储, 要使用的时候再通过JSON技术把文本解析成数据对象&#xff…

Word 将页面方向更改为横向或纵向

文章目录 更改整个文档的方向更改部分页面的方向方法1&#xff1a;方法2&#xff1a; 参考链接 更改整个文档的方向 选择“布局”>“方向”&#xff0c;选择“纵向”或“横向”。 更改部分页面的方向 需要达到下图结果&#xff1a; 方法1&#xff1a; 选:中你要在横向页面…

ThreadLocal为什么存在内存泄漏,源码分析

文章目录 1. ThreadLocal的使用场景2. 弱引用与内存泄露3. 源码分析①&#xff1a;ThreadLocalMap②&#xff1a;set操作③&#xff1a;get操作④&#xff1a;remove操作 4. 继承性 InheritableThreadLocal5. 各类ThreadLocal问题总结 1. ThreadLocal的使用场景 通常&#xff0…

计算机网络复习6

应用层 文章目录 应用层网络应用模型域名系统DNS文件传输协议FTP电子邮件万维网 网络应用模型 客户/服务器模型 客户/服务器&#xff08;Client/Server&#xff0c;C/S)模型中&#xff0c;有一个总是打开的主机称为服务器&#xff0c;它服务于许多来自其他称为客户机的主机请求…

SparkStreaming_window_sparksql_reids

1.5 window 滚动窗口滑动窗口 window操作就是窗口函数。Spark Streaming提供了滑动窗口操作的支持&#xff0c;从而让我们可以对一个滑动窗口内的数据执行计算操作。每次掉落在窗口内的RDD的数据&#xff0c;会被聚合起来执行计算操作&#xff0c;然后生成的RDD&#xff0c;会…

Stable Diffusion WebUI安装合成面部说话插件SadTalker

SadTalker可以根据一张图片、一段音频&#xff0c;合成面部说这段语音的视频。图片需要真人或者接近真人。 安装ffmpeg 下载地址&#xff1a; https://www.gyan.dev/ffmpeg/builds/ 下载ffmpeg-git-full.7z 后解压&#xff0c;将解压后的目录\bin添加到环境变量的Path中。 在…

鸿蒙原生应用再添新丁!爱奇艺入局鸿蒙

鸿蒙原生应用再添新丁&#xff01;爱奇艺 入局鸿蒙 来自 HarmonyOS 微博12月29日消息&#xff0c;#爱奇艺完成鸿蒙原生应用Beta版#作为中国头部在线视频平台&#xff0c;爱奇艺 完成鸿蒙原生应用Beta版&#xff0c;将以丰富的正版高清视频资源促进鸿蒙生态的进一步繁荣&#x…

python实现图像的二维傅里叶变换——冈萨雷斯数字图像处理

原理 二维傅里叶变换是一种在图像处理中常用的数学工具&#xff0c;它将图像从空间域&#xff08;我们通常看到的像素排列&#xff09;转换到频率域。这种变换揭示了图像的频率成分&#xff0c;有助于进行各种图像分析和处理&#xff0c;如滤波、图像增强、边缘检测等。 在数学…

YOLOv5算法进阶改进(10)— 更换主干网络之MobileViTv3 | 轻量化Backbone

前言:Hello大家好,我是小哥谈。MobileViTv3是一种改进的模型架构,用于图像分类任务。它是在MobileViTv1和MobileViTv2的基础上进行改进的,通过引入新的模块和优化网络结构来提高性能。本节课就给大家介绍一下如何在主干网络中引入MobileViTv3网络结构,希望大家学习之后能够…

Stable Diffusion WebUI制作光影文字效果

在huggingface上下载control_v1p_sd15_brightness模型。 将模型放在stable-diffusion-webui\extensions\sd-webui-controlnet\models目录下。 SD参数配置 正向提示词&#xff1a; city,Building,tall building,Neon Light, gentle light shines through, anime style, paint…

冒泡排序--------(C每日一题)

冒泡排序&#xff1a; 每次将相邻的两个数比较,将小的调到前头--升序 冒泡排序一个结论&#xff1a; n个数要进行n-1轮比较&#xff0c;第j轮要进行n-j次两两比较 循环体代码&#xff1a; int main() {int i, j,n,a[10],t;//n是几个数比较for(j1;j<n-1;j)//控制轮次for…

PNG免抠素材库,免费下载,可商用~

本期分享5个高质量PNG素材网站&#xff0c;让你在工作中大大提高效率&#xff0c;节省更多的时间&#xff0c;赶紧收藏起来吧~ 1、菜鸟图库 https://www.sucai999.com/searchlist/66008----all-0-1.html?vNTYxMjky 网站主要分享设计素材为主。像平面海报、免抠元素、背景图片…

英语打卡分析12

[爱心]长难句分享第十二天解析 [玫瑰]【词汇】&#xff1a; • appropriate [əˈproʊpriət] adj. 恰当的 • in place 准备妥当 • caregiver [ˈkerɡɪvər] n. 看护人 • no more … than… 和……一样不 • newsworthy [ˈnuːzwɜːri] adj. 值得报道的 • capable […

记一次应急响应练习(Linux)

记一次应急响应练习(Linux) Linux&#xff1a; 请提交攻击者的IP地址 答&#xff1a; 192.168.31.132 思路&#xff1a; 通过查看历史命令和开放的8080端口看到这台主机上运行的是Tomcat服务。并且在历史命令中看到了Tomcat的安装路径。那么就算是找到了日志的查看点了&#x…

SpringBoot3 核心技能

1. 常用注解 SpringBoot摒弃XML配置方式&#xff0c;改为全注解驱动 1. 组件注册 Configuration、SpringBootConfiguration Bean、Scope Controller、 Service、Repository、Component Import ComponentScan 步骤&#xff1a; 1、Configuration 编写一个配置类 2、在…