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

迭代器 生成器 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);
  });

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_36158551/article/details/135230197