preface

The simple use of async and await will not be described here. Many front-end pain points can be solved by one or two keywords in ES6 and ES7, but are eventually converted into ES5 syntax by Babel in most cases.

As a daily CV front-end, I would like to know more about it. Maybe one day I can save an overnight

Chatter of the Generator

Relevant methods

Generator.prototype.next() returns a value generated by the yield expression

The Generator. The prototype. The return () returns the value of a given Generator and an end

The Generator. The prototype. Throw () to the Generator throw an error

Basic usage

function* gen() {
try {
  let first = yield 1;
  let second = yield first + 2;
  yield second + 3;
  } catch (e){
    console.log(e); }}var iterator = gen();
console.log(iterator.next());    // {value: 1, done: false}
console.log(iterator.next(4));   // {value: 6, done: false}
console.log(iterator.next());    // {value: NaN, done: false}
console.log(iterator.next());    // {value: undefined, done: true}
console.log(iterator.return();   // { value: undefined, done: true }
console.log(iterator.return(1);   // { value: 1, done: true }
iterator.throw('Wrong');    / / make a mistake

Copy the code

If you answered all of the above questions correctly, you have mastered the basics.

Object to… , the for of

A data structure that deploys the symbol. iterator attribute can use for… Go through with… Operator operation

Iterator Object does not have a Symbol. Iterator. This will cause an error when used directly

let obj = {
            0: 'a'.1: 'b'.2: 'c',}for(let p of obj){
            console.log(p);//TypeError: obj is not iterable
      }
Copy the code

So you need to add a generator method on Object

console.log([ // ... Array.from. {0: 1.1: 2.2: 3.length: 3[Symbol.iterator]:function* (){
          let index = 0;
          while(index ! = =this.length){
              yield this[index++]; }}// [Symbol.iterator]() {
    // let len = this.length;
    // let index = 0;
    // // iterators have a next method and return value,done after the method is executed
    // return {
    // next: () => {
    // return { value: this[index++], done: index === len + 1 };
    / /}
    / /};
    / /}}]);Copy the code

Regenerator converter

During the compilation phase, the corresponding abstract syntax tree (AST) needs to be processed to generate ES5 syntax structures that conform to the runtime code. In the runtime phase, runtime functions are added to assist the compiled statement execution.

The ReGenerator website provides visual operations. An example before and after simple AST transcoding is as follows:

function *range(max, step) {
  var count = 0;
  step = step || 1;

  for (var i = 0; i < max; i += step) {
    count++;
    yield i;
  }

  return count;
}

var gen = range(20.3), info;

while(! (info = gen.next()).done) {console.log(info.value);
}

console.log("steps taken: " + info.value);
Copy the code

After the transformation

ar _marked =
/*#__PURE__*/
regeneratorRuntime.mark(range);

function range(max, step) {
  var count, i;
  return regeneratorRuntime.wrap(function range$(_context) {
    while (1) {
      switch (_context.prev = _context.next) {
        case 0:
          count = 0;
          step = step || 1;
          i = 0;

        case 3:
          if(! (i < max)) { _context.next =10;
            break;
          }

          count++;
          _context.next = 7;
          return i;

        case 7:
          i += step;
          _context.next = 3;
          break;

        case 10:
          return _context.abrupt("return", count);

        case 11:
        case "end":
          return _context.stop();
      }
    }
  }, _marked);
}

var gen = range(20.3),
    info;

while(! (info = gen.next()).done) {console.log(info.value);
}

console.log("steps taken: " + info.value);
Copy the code

Excellent CO library to solve asynchronous problems before async and await

Co is an open source project launched by TJ in 2013 that uses ES6 Generator functions to solve asynchronous operations.

A key part

/**
 * Execute the generator function or a generator
 * and return a promise.
 *
 * @param {Function} fn
 * @return {Promise}
 * @api public* /

function co(gen) {
  // Hold the context
  var ctx = this;
  // array.prototype. slice removes passed method names and leaves arguments
  var args = slice.call(arguments.1);

  // we wrap everything in a promise to avoid promise chaining,
  // which leads to memory leak errors.
  // see https://github.com/tj/co/issues/180
  Co () returns a Promise object
  return new Promise(function(resolve, reject) {
  	// Execute a Generator to get the traverser
    if (typeof gen === 'function') gen = gen.apply(ctx, args);
    if(! gen ||typeofgen.next ! = ='function') return resolve(gen);
	// Execute the success callback
    onFulfilled();

    / * * *@param {Mixed} res
     * @return {Promise}
     * @api private* /

    function onFulfilled(res) {
      var ret;
      try {
        ret = gen.next(res);
      } catch (e) {
        return reject(e);
      }
      next(ret);
      return null;
    }

    / * * *@param {Error} err
     * @return {Promise}
     * @api private* /

    function onRejected(err) {
      var ret;
      try {
        ret = gen.throw(err);
      } catch (e) {
        return reject(e);
      }
      next(ret);
    }

    /**
     * Get the next value in the generator,
     * return a promise.
     *
     * @param {Object} ret
     * @return {Promise}
     * @api private* /
    // Execute next continuously
    function next(ret) {
      // Generator completed
      if (ret.done) return resolve(ret.value);
      // Each time the yield value is converted to a promise
      var value = toPromise.call(ctx, ret.value);
      // call consecutively with promise.then
      // Onpity, onRejected will continue to call next itself
      if (value && isPromise(value)) return value.then(onFulfilled, onRejected);
      // Yield cannot be converted to promise
      return onRejected(new TypeError('You may only yield a function, promise, generator, array, or object, '
        + 'but the following object was passed: "' + String(ret.value) + '"')); }}); }Copy the code

async,await

What are async,await functions? In short, it is the syntactic sugar of Generator functions.

Reference documentation

Syntax for Generator functions

Asynchronous application of Generator functions

Async function