ES6 syntax features (2) Introduction to iterator generator Promise

Introduction to iterator generator Promise

1. Iterator

  Iterator is a mechanism to implement unified traversal operations on different collections. Just deploy the Iterator interface to the data structure that needs to be traversed, and implement the traversal operation by calling the interface, or using the API that consumes the interface.
  ES6 introduces an implicitly standardized interface for iterators. Many built-in data structures in Javascript, such as Array, Map, Set, String, TypedArray, function arguments objects, and NodeList objects all have the Iterator interface.
  The Iterator interface is mainly used for for of. For of (it traverses the value
) is different from for in (it traverses the key).

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

Insert image description here
  You can print an Array instance on the console to see that its prototype has a Symbol.iterator attribute (Symbol.iterator is actually the abbreviation of Symbol ('Symbol.iterator'). The attribute name is the Symbol type, which represents the unique and unique nature of this attribute. Overriding), it is the iterator function. When this function is executed, an iterator object will be returned, and there is a next() method under the object.

1.1. next() iteration

  When the last element of the array is obtained, the iterator will not report done:true. At this time, next() needs to be called again to pass the value at the end of the array to get the completion signal done:true.
Normally, continuing to call the next method on an iterator object that has been iterated will continue to return {value: undefined, done: true} without reporting an error.

1.2. Implement custom traversed data

  Customize the list data of traversing obj instead of 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);
      }

Insert image description here

2. Generator

  A generator is a special function and a new solution for asynchronous programming. Adding an * between function and the function name
  returns an iterator object that can be used to call
  the yield function code using the next() method.

  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());

Insert image description here
  The iterator object can be used to
  output the code behind yield.

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

Insert image description here

2.1. Generator passes parameters

  The parameters passed by the next() method will be used as the return value of the previous 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. Case

2.2.1. Requirement 1

  111 is output after 1s, 222 is output after 2s, and 333 is output after 3s. The total time is 6s
  (1) Traditional writing method (callback hell)

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

  (2) Generator writing method (elegant)

  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. Requirement 2

  Return order information through user information Return product information 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 is a new solution for asynchronous programming introduced in ES6. Promise is a constructor that encapsulates asynchronous operations and can obtain the results of success.then() or failure.catch().
  .then(a, b) can have two parameters, a means success and b means failure; b can also be omitted and use .catch() to return an error

    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. Reading a single file

  (1) node error priority mechanism

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

  (2) Use promise encapsulation to read non-existent files and report errors.

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);
});

Insert image description here

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 packaging

<!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 can be called in a chain to solve the problem of callback hell.
  If an empty or non-promise type object is returned, the status is success and the value is the value of the return (undefined if not returned)

   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);

Insert image description here
  return a promise object (the state returned by the object is the state of the then return value

      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. Reading multiple files

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

Insert image description here

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);
  });

Insert image description here

Guess you like

Origin blog.csdn.net/qq_36158551/article/details/135230197