ES6 Generator 函数

Generator 函数是 ES6 提供的一种异步编程解决

一、Generator 函数简介

1.概述

Generator函数是一个状态机,封装了多个内部状态

Generator函数还是一个遍历器对象生成函数,返回遍历器对象

2.特点

1.function关键字与函数名之间有一个星号

2.函数体内部使用yield表达式,定义不同的内部状态

二、Generator函数用法

function* helloWorldGenerator() {
  yield 'hello';
  yield 'world';
  return 'ending';
}

//调用函数不会立即执行,而是返回遍历器对象
var hw = helloWorldGenerator();  
hw.next()  // { value: 'hello', done: false }
hw.next()  // { value: 'world', done: false }
hw.next()  // { value: 'ending', done: true }
hw.next()  // { value: undefined, done: true }

调用 Generator 函数,返回一个遍历器对象,代表 Generator 函数的内部指针。以后,每次调用遍历器对象的next方法,就会返回一个有着value和done两个属性的对象。value属性表示当前的内部状态的值,是yield表达式后面那个表达式的值;done属性是一个布尔值,表示是否遍历结束。

三、yield表达式和next()方法

1.yield表达式

Generator 函数返回的遍历器对象,只有调用next方法才会遍历下一个内部状态,所以其实提供了一种可以暂停执行的函数。

yield表达式就是暂停标志。

yield表达式后面的表达式,只有当调用next方法、内部指针指向该语句时才会执行。

使用yield需注意:
(1).yield表达式只能用在 Generator 函数里面
(2).yield表达式如果用在另一个表达式之中,必须放在圆括号里面

function* demo() {
  console.log('Hello' + yield); // SyntaxError
  console.log('Hello' + yield 123); // SyntaxError

  console.log('Hello' + (yield)); // OK
  console.log('Hello' + (yield 123)); // OK
}

yield与return的异同:
(1).next()遇到yield与return均会暂停
(2).函数内部只能有一个return,但是可以有多个yield
(3).yield能够记录位置,下一次从该位置继续执行,return不会记录位置

2.next方法参数

next方法可以带一个参数,该参数就会被当作上一个yield表达式的返回值。

function* foo(x) {
  var y = 2 * (yield (x + 1));
  var z = yield (y / 3);
  return (x + y + z);
}

var a = foo(5);
a.next() // Object{value:6, done:false}
a.next() // Object{value:NaN, done:false}
a.next() // Object{value:NaN, done:true}

var b = foo(5);
b.next() // { value:6, done:false }
b.next(12) // { value:8, done:false }
b.next(13) // { value:42, done:true }
//第一次调用b的next方法时,返回x+1的值6;
第二次调用next方法,将上一次yield表达式的值设为12,因此y等于24,返回y / 3的值8;
第三次调用next方法,将上一次yield表达式的值设为13,因此z等于13,这时x等于5,y等于24,所以return语句的值等于42

3.for…of循环

for…of循环可以自动遍历 Generator 函数运行时生成的Iterator对象

function* foo() {
 yield 1;
 yield 2;
 yield 3;
 yield 4;
 yield 5;
 return 6;
}

for (let v of foo()) {
 console.log(v);
}
// 1 2 3 4 5
//注意:next方法的返回对象的done属性为true,for...of循环就会中止,且不包含该返回对象

4.yield* 表达式

yield*表达式,用来在一个Generator函数里执行另一个Generator函数。

function* foo() {
  yield 'a';
  yield 'b';
}

function* bar() {
  yield 'x';
  yield* foo();
  yield 'y';
}
// 等同于
function* bar() {
  yield 'x';
  yield 'a';
  yield 'b';
  yield 'y';
}

四、Genarator函数示例

1.实现斐波那契数列

使用for…of循环实现斐波那契数列

function* fibonacci() {
  let [prev, curr] = [0, 1];
  for (;;) {
    yield curr;
    [prev, curr] = [curr, prev + curr];
  }
}

for (let n of fibonacci()) {
  if (n > 1000) break;
  console.log(n);
}

2.异步操作的同步化表达

将异步操作写在yield表达式里面,需要异步操作的后续操作放在yield表达式下面,等到调用next方法时再执行

function* loadUI() {
  showLoadingScreen();
  yield loadUIDataAsynchronously();
  hideLoadingScreen();
}
var loader = loadUI();
// 加载UI
loader.next()

// 卸载UI
loader.next()

扩展:异步编程

1.什么是异步编程

如果程序调用某个方法,等待其执行全部处理后才能继续执行,我们称其为同步的。相反,在处理完成之前就返回调用方法则是异步的。

异步编程一般会在方法执行之前注册一个事件,等待方法真正执行完成后通过该事件获取返回结果

2.试用场景

异步编程适用于高IO的场景

3.异步编程方式

ES6 诞生以前,异步编程的方法,大概有下面四种:

1)回调函数

(2)事件监听

(3)发布/订阅者

(4)Promise对象

Generator 函数将 JavaScript 异步编程带入了一个全新的阶段

https://es6.ruanyifeng.com/#docs/generator
|
https://blog.csdn.net/ganyingxie123456/article/details/78152770?utm_medium=distribute.pc_relevant.none-task-blog-OPENSEARCH-3.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-3.control

你可能感兴趣的:(ECMAScript6,es6)