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++;
}
4Hã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[];
2Hã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ư sauvar 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 functionInput 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