Generator function javascript là gì

Trong javascript một khi function được thực thi thì nó sẽ được đảm bảo

var x = 1;

function *foo[] {
  x++;
  yield;
  console.log[ "x:", x ];
}

function bar[] {
  x++;
}
3 tức là những phần code khác không thể can thiệp, làm gián đoạn quá trình chạy của function đó. Tuy nhiên ES6 đã cho ra mắt 1 loại function mới mà không hành xử theo lẽ thông thường như thế -
var x = 1;

function *foo[] {
  x++;
  yield;
  console.log[ "x:", x ];
}

function bar[] {
  x++;
}
4

Hãy xem xét ví dụ sau đây:

var x = 1;
function foo[] {
  x++;
  bar[];
  console.log[ "x:", x ];
}

function bar[] {
  x++;
}

foo[];

Chúng ta có thể thấy function

var x = 1;

function *foo[] {
  x++;
  yield;
  console.log[ "x:", x ];
}

function bar[] {
  x++;
}
5 được gọi bên trong function
var x = 1;

function *foo[] {
  x++;
  yield;
  console.log[ "x:", x ];
}

function bar[] {
  x++;
}
6 và giá trị của x sau khi gọi foo[] là 3. Trong trường hợp không có lời gọi
var x = 1;

function *foo[] {
  x++;
  yield;
  console.log[ "x:", x ];
}

function bar[] {
  x++;
}
7 bên trong
var x = 1;

function *foo[] {
  x++;
  yield;
  console.log[ "x:", x ];
}

function bar[] {
  x++;
}
6 giá trị của
var x = 1;

function *foo[] {
  x++;
  yield;
  console.log[ "x:", x ];
}

function bar[] {
  x++;
}
9 sẽ là 2. Hãy tưởng tượng bằng 1 cách nào đó mặc dù chúng ta không gọi
var x = 1;

function *foo[] {
  x++;
  yield;
  console.log[ "x:", x ];
}

function bar[] {
  x++;
}
7 ở bên trong
var x = 1;

function *foo[] {
  x++;
  yield;
  console.log[ "x:", x ];
}

function bar[] {
  x++;
}
6 mà kết quả trả về vẫn là 3 ??? Đó chính là lúc mà chúng ta sử dụng
var it = foo[];
it.next[];
x;                      // 2
bar[];
x;                      // 3
it.next[];
2

Hãy thay đổi đoạn code 1 chút

var x = 1;

function *foo[] {
  x++;
  yield;
  console.log[ "x:", x ];
}

function bar[] {
  x++;
}

Bạn có để ý thấy sự khác biệt ?

Chúng ta đã có 1

var it = foo[];
it.next[];
x;                      // 2
bar[];
x;                      // 3
it.next[];
3 với khai báo
var it = foo[];
it.next[];
x;                      // 2
bar[];
x;                      // 3
it.next[];
4 - chú ý dấu
var it = foo[];
it.next[];
x;                      // 2
bar[];
x;                      // 3
it.next[];
5 trong phần khai báo.

Và sử dụng

var it = foo[];
it.next[];
x;                      // 2
bar[];
x;                      // 3
it.next[];
2 như sau

var it = foo[];
it.next[];
x;                      // 2
bar[];
x;                      // 3
it.next[];

Xem xét từng bước một của quá trình trên:

Như vậy chúng ta có thể gọi

var x = 1;

function *foo[] {
  x++;
  yield;
  console.log[ "x:", x ];
}

function bar[] {
  x++;
}
5 bên ngoài
var x = 1;

function *foo[] {
  x++;
  yield;
  console.log[ "x:", x ];
}

function bar[] {
  x++;
}
6 và kết quả cuối cùng của
var x = 1;

function *foo[] {
  x++;
  yield;
  console.log[ "x:", x ];
}

function bar[] {
  x++;
}
9 vẫn là 3. Chúng ta có thể coi điều này như là 1 sự phá vỡ rule
var x = 1;

function *foo[] {
  x++;
  yield;
  console.log[ "x:", x ];
}

function bar[] {
  x++;
}
3 của function

Input và output

var it = foo[];
it.next[];
x;                      // 2
bar[];
x;                      // 3
it.next[];
2 là 1 function đặc biệt nhưng nó vẫn là 1 function nên nó vẫn có thể có tham số truyền vào -
function *foo[x,y] {
  return x * y;
}

var it = foo[ 6, 7 ];

var res = it.next[];

res.value;
2 và giá trị trả về -
function *foo[x,y] {
  return x * y;
}

var it = foo[ 6, 7 ];

var res = it.next[];

res.value;
3 như 1 function thông thường.

function *foo[x,y] {
  return x * y;
}

var it = foo[ 6, 7 ];

var res = it.next[];

res.value;

Chúng ta vẫn có thể truyền giá trị đầu vào 6 và 7 cho

var x = 1;

function *foo[] {
  x++;
  yield;
  console.log[ "x:", x ];
}

function bar[] {
  x++;
}
9 và
function *foo[x,y] {
  return x * y;
}

var it = foo[ 6, 7 ];

var res = it.next[];

res.value;
5Cách gọi function cũng khá quen thuộc -
function *foo[x,y] {
  return x * y;
}

var it = foo[ 6, 7 ];

var res = it.next[];

res.value;
6 nhưng cách mà chúng ta nhận về kết quả có đôi chút khác biệt.

Đầu tiên

function *foo[x,y] {
  return x * y;
}

var it = foo[ 6, 7 ];

var res = it.next[];

res.value;
6 không thực thi function từ đầu đến cuối mà như đã đề cập lúc trước, nó tạo ra 1
function *foo[x,y] {
  return x * y;
}

var it = foo[ 6, 7 ];

var res = it.next[];

res.value;
8. Khi
function *foo[x,y] {
  return x * y;
}

var it = foo[ 6, 7 ];

var res = it.next[];

res.value;
9 được gọi, nó thực thi các lệnh trong function cho đến khi gặp
function *foo[x] {
  var y = x * [yield];
  return y;
}

var it = foo[ 6 ];

it.next[];

var res = it.next[ 7 ];

res.value;      // 42
0 hoặc kết thúc function. Giá trị trả về của lênh
function *foo[x,y] {
  return x * y;
}

var it = foo[ 6, 7 ];

var res = it.next[];

res.value;
9 này là 1 object có thuộc tính
function *foo[x] {
  var y = x * [yield];
  return y;
}

var it = foo[ 6 ];

it.next[];

var res = it.next[ 7 ];

res.value;      // 42
2 và chúng ta sẽ lấy giá trị từ thuộc tính này.

Iteration Messaging

Với lệnh

function *foo[x] {
  var y = x * [yield];
  return y;
}

var it = foo[ 6 ];

it.next[];

var res = it.next[ 7 ];

res.value;      // 42
0 đứng độc lập, ta có thể coi đó như 1 điểm dừng để thực hiện những xử lí chen vào giữa quá trình thực thi của function [có vẻ giống
function *foo[x] {
  var y = x * [yield];
  return y;
}

var it = foo[ 6 ];

it.next[];

var res = it.next[ 7 ];

res.value;      // 42
4 mà mình vẫn hay dùng] nhưng thực thế là cách sử dụng của nó còn linh hoạt hơn thế.

function *foo[x] {
  var y = x * [yield];
  return y;
}

var it = foo[ 6 ];

it.next[];

var res = it.next[ 7 ];

res.value;      // 42

Ở đây ta có thể sử dụng

function *foo[x] {
  var y = x * [yield];
  return y;
}

var it = foo[ 6 ];

it.next[];

var res = it.next[ 7 ];

res.value;      // 42
0 như 1 nơi để truyền tham số vào Chuôĩ câu lệnh trên truyền 6 là giá trị đầu vào cho
var x = 1;

function *foo[] {
  x++;
  yield;
  console.log[ "x:", x ];
}

function bar[] {
  x++;
}
9 và truyền 7 như là gía trị cho
function *foo[x] {
  var y = x * [yield];
  return y;
}

var it = foo[ 6 ];

it.next[];

var res = it.next[ 7 ];

res.value;      // 42
0 và gía trị sau khi tính toán là 6*7=42.

Câu chuyện ở đây là gì ? Câu lệnh

function *foo[x] {
  var y = x * [yield];
  return y;
}

var it = foo[ 6 ];

it.next[];

var res = it.next[ 7 ];

res.value;      // 42
8 đầu tiên bắt đầu
var it = foo[];
it.next[];
x;                      // 2
bar[];
x;                      // 3
it.next[];
2 và chạy cho đến khi gặp
function *foo[x] {
  var y = x * [yield];
  return y;
}

var it = foo[ 6 ];

it.next[];

var res = it.next[ 7 ];

res.value;      // 42
0. Khi gặp lệnh
function *foo[x] {
  var y = x * [yield];
  return y;
}

var it = foo[ 6 ];

it.next[];

var res = it.next[ 7 ];

res.value;      // 42
0,
function *foo[x] {
  var y = x * [yield];
  return y;
}

var it = foo[ 6 ];

it.next[];

var res = it.next[ 7 ];

res.value;      // 42
0 đặt ra câu hỏi giá trị truyền vào ở đây là gì. Câu lệnh
function *foo[x] {
  var y = x * [yield];
  return y;
}

var it = foo[ 6 ];

it.next[];

var res = it.next[ 7 ];

res.value;      // 42
8 đầu tiên đã hoàn thành xong nhiệm vụ của mình vậy nên trách nhiệm trả lời này sẽ nằm trong câu lệnh
function *foo[x] {
  var y = x * [yield];
  return y;
}

var it = foo[ 6 ];

it.next[];

var res = it.next[ 7 ];

res.value;      // 42
8 tiếp theo. Khi lệnh
function *foo[x] {
  var y = x * [yield];
  return y;
}

var it = foo[ 6 ];

it.next[];

var res = it.next[ 7 ];

res.value;      // 42
8 tiếp theo được thực hiện, nó trả lời cho câu hỏi mà
function *foo[x] {
  var y = x * [yield];
  return y;
}

var it = foo[ 6 ];

it.next[];

var res = it.next[ 7 ];

res.value;      // 42
0 đặt ra mà thực thi nốt phần còn lại.

Muliple iterators

Mỗi khi chúng ta tạo một iterator thì chúng ta cũng đã tạo 1 generator instance. Khi có nhiều instance của cùng 1 generator thì chúng có thể tương tác với nhau.

function *foo[] {
  var x = yield 2;
  z++;
  var y = yield [x * z];
  console.log[ x, y, z ];
}

var z = 1;

var it1 = foo[];
var it2 = foo[];

var val1 = it1.next[].value;            // 2 

Chủ Đề