Home  >  Article  >  Web Front-end  >  Introduction to ES6 generator usage (with examples)

Introduction to ES6 generator usage (with examples)

不言
不言forward
2019-03-18 11:19:212376browse

This article brings you an introduction to the usage of the ES6 generator (with examples). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

Concept

The generator is obtained by running the generator function (generator function) and is iterable.

function* gen() { 
  yield 'a';
  yield 'b';
  yield 'c';
}

let g = gen(); 
// "Generator { }"

Principle and simple application

The generator has a great feature, it can pause the internal code running and return a value to the external function. (After pausing, other code will not be prevented from running.) When its next method is called externally, it will continue to execute the remaining code and accept a parameter from the outside. This implementation mainly relies on the keyword yield .

The yield keyword causes the execution of the generator function to pause, and the value of the expression following the yield keyword is returned to the caller of the generator. It can be thought of as a generator-based version of the return keyword.

function* g(){
    var a = yield 2;
    console.log(a);
}

var it = g(); // 返回一个可迭代的生成器对象
console.log(it.next()); // 执行生成器函数内部代码,第一次返回 {done: false, value: 2}
it.next(3); // 继续执行生成器函数内部代码,同时向生成器传递参数3,最后返回 {done: true, value: undefined}

A simple counter

function* count(){
    var n = 1;
    while(true){
        yield n++;
    }
}

var it = count();
it.next(); // 1
it.next(); // 2
it.next(); // 3

Write asynchronous code in a synchronous way

In the past, asynchronous ajax request results were processed, generally Use the method of passing callback function. Once you encounter multiple levels of callback nesting, the readability of the code will be reduced, and debugging will be inconvenient. With the generator, we can write asynchronous code in a synchronous way. This sounds very interesting. Our code will be like this

function foo(){
    var result = asyncFun(); // asyncFun 是异步函数,result 是异步返回的结果
    console.log(result);
}

Of course, the above code does not get the correct result, it is just an idea. We're going to do it with generators, and it works. Think about the characteristics of the generator:

  1. It can pause and return values ​​to the outside
  2. It can continue to execute the remaining code and accept parameters from the outside

that's enough. With the generator function in place, now we redesign the code:

function* foo(){
    // 这里遇到了异步方法,必须停下来。
    // 等待异步方法执行完毕,并返回结果,继续运行代码。当然,同步 ajax 不能算,它不是异步
    // 输出结果
}

Sit down and think about the keywords related to pause and continue. Stop...continue...stop...continue...stop...continue...Don't...Stop...Don't...Stop... Don't...Stop...these two words are yield, next.

function *foo(){
    var result = yield asyncFun(next);
    console.log(result);
}

When the code encounters yield will be paused. At this time, the asyncFun function will not be paused, but will be executed. After the execution is completed, the next method of the generator will be called, and the return result will be The parameters are passed to next. Since we cannot get next inside the generator function, we must use global variables to pass next.

var next, gn;

function asyncFun(next){
    // 模拟异步请求
    setTimeout(function(){
        // 返回一个随机数
        next(Math.random())
    }, 1000)
}

function* foo(){
    var result = yield asyncFun(next);
    console.log(result);
}

gn = foo();
next = gn.next.bind(gn);
next(); // 打印随机数

Written like this, running seems a bit heavy. You can write a wrapper function to run a generator function containing asynchronous code.

function asyncFun(next){
  // 模拟异步请求
  setTimeout(function(){
    // 返回一个随机数
    next(Math.random())
  }, 1000)
}

function* foo(){
  var result = yield function(next){asyncFun(next)};
  console.log(result);
}



function wrapFun (gFn){
  var gn = foo(),
      next = gn.next.bind(gn);
  next().value(next);
}

wrapFun(foo);

Demo address

However, since Promise and await were released, this combination is used more often , its use is also simpler and its scope is wider.

The above is the detailed content of Introduction to ES6 generator usage (with examples). For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete
Previous article:What is AngularNext article:What is Angular