1. Iterator

1.1 Basic Concepts

  • Iterator is a mechanism (interface), not a standard class provided by ES6. It provides a unified access mechanism for various data structures. The Iterator interface can be deployed remotely on any data structure to complete Iterator operations and process all members of the data structure in turn
    • A member that has the next method for traversing the data structure once
    • {done: false, value: XXX}
      • Done Indicates whether the traversal is complete
      • Value Current traversal result
class Iterator {
  constructor(arr) {
    this.arr = arr;
    this.index = 0;
  }
  next() {
    let index = this.index;
    let arr = this.arr;
    if (index > arr.length -1) {
      return {
        done: true.valur: undefined}; }return {
      done: false.valur: arr[this.index++],  // Calculate the value first, then ++}; }}let arr = [10.20.30]
let itor = new Iterator(arr)

console.log(itor.next())  // {done: false, valur: 10}
console.log(itor.next())  // {done: false, valur: 20}
console.log(itor.next())  // {done: false, valur: 30}
console.log(itor.next())  // {done: true, valur: undefined}
Copy the code

1.2 Built-in Symbol. Iterator property

  • Data structures (values) that have the symbol. iterator attribute, known as traversable, can be processed based on a for of loop

    • Prototype -> Symbol(Symbol. Iterator)
    • Arguments /NodeList (node collection) /HTMLCollection…
    • String
    • Set
    • Map
    • generator object
  • Iterator object does not have the Symbol. Iterator property by default and is a non-iterable data structure

  • Reconstructing the traverser for ARR

    • The for of/expansion operator traverses the calendar mechanism
let arr = [10.20.30];
arr[Symbol.iterator] = function() {
  // Return an iterator object with the next method
  let index = 0;
  let self = this;
  return {
    next() {
      console.log('OK')
      if (index > self.length -1) {
        return {
          done: true.value: undefined}; }let result = {
        done: false.value: self[index++],
      };
      return result
    }
  };
};
for (let item of arr) {
  console.log(item)
}
console.log(... arr)Copy the code
  • The object itself is not a data structure conforming to the iterator traversal specification
let obj = {
  0: 10.1: 20.2: 30.length: 3
};
for(let item of obj) {
  console.log(item)
}
// Uncaught TypeError: obj is not iterable
Copy the code
  • Let array-like objects be traversed
let obj = {
  0: 10.1: 20.2: 30.length: 3.// [Symbol.iterator]:Array.prototype[Symbol.iterator]
  [Symbol.iterator]: function() {
    let index = 0;
    let self = this;
    return {
      next() {
        return index>self.length-1? {done: true.vaule: undefined}, {done: false.value: self[index++]}
      }
    }
  }
};
for(let item of obj) {
  console.log(item)
}
/ / 10 20 to 30
Copy the code
  • To allow pure objects to be traversed

  • Symbol is a unique value that iterates through its own iterator and cannot be excluded

2. Generator objects

2.1 Basic usage of generator functions

  • The producer object is returned by a generator function and conforms to both the iterable and Iterator protocols

  • Add the * generator function

function* func() {

}
func.prototype.AA = '10'
let iterator = func();

The return value is an instance of the current func
// iterator.__proto__ === func.protorype
// console.log(iterator instanceof func) // true
// func itself cannot be new

console.log(iterator)
Copy the code

  • usage
function* func() {
  console.log('A');
  yield 1;
  console.log('B');
  yield 2;
  console.log('C');
  yield 3;
  console.log('D');
}
let iterator = func();
console.log(iterator.next());  // 遇到一个yield就结束,再打印,从上一次yiled到下一个yield
Copy the code

2.2 Next argument, assigning the yield return value

function* func() {
  let x = yield 1;
  console.log(x);   / / - > 10
}
let iterator = func();
iterator.next()   // {vaule: 1, done: false}
iterator.next()   // x is undefined {vaule: undefined, done: true}If the iterator. Next (10),yieldThe return value is10, assign x, x prints10 
Copy the code

2.3 Calling another generator function from one generator

function* func1() {
  yield 1;
  yield 2;
}
function* func2() {
  yield 3;
  yield* func1();
  yield 4;
}
let iterator = func2();
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
Copy the code

3 Writing method of the call

  • Async +await is a syntactic sugar processed by generator+ Promise

3.1 Writing method of asynchronous serial THEN call

const func = x= > {
  return new Promise(resolve= > {
    setTimeout(() = > {
      reslove(++x);   // ++x accumulates before operation
    }, 1000)})}// in asynchronous serial writing, the last return value is passed to the next
func(0).then(x= > {
  console.log(x);  / / 1
  return func(x);
}).then(x= > {
  console.log(x);  / / 2
  return func(x);
}).then(x= > {
  console.log(x);  / / 3
})
Copy the code

3.2 saync/await

(async function anonymous() {
  let x = await func(0);
  console.log(x)
  x = await func(x)
  console.log(x)
   x = await func(x)
  console.log(x)
})();
Copy the code

3.3 the generator writing

function* generator(x) {
  x = yield func(x);
  console.log(x);   / / 1
  
  x = yield func(x);
  console.log(x);  / / 2
}

// Know how many times, write dead
let iterator = generator(0);
let result = iterator.next();  Return a promise instance,{value: promise, done: false}
result.value.then(x= > {
  result = iterator.next(x);  // The first result is passed as a value
  result.value.then(x= >{ result = iterator.next(x); })});// generator generator function, params initially executes the parameters passed by generator
function async(generator, ... params) {
  constiterator = generator(... params); }Copy the code