function* và yield trong Javascript generator function
function* là một trong những chức năng mới của Javascript trong ECMAScript 2015 (6th Edition, hay tắt là ES6). function* giúp khai báo 1 generator function, trả về 1 Generator object . Với chức năng mới này, hàm có thể dừng thực thi bất cứ thời điểm nào, đợi async chạy xong, xong tiếp tục thực ...
function* là một trong những chức năng mới của Javascript trong ECMAScript 2015 (6th Edition, hay tắt là ES6). function* giúp khai báo 1 generator function, trả về 1 Generator object.
Với chức năng mới này, hàm có thể dừng thực thi bất cứ thời điểm nào, đợi async chạy xong, xong tiếp tục thực thi.
Có thể hiểu Generator function là một function, có khả năng tạm ngưng thực thi trước khi hàm kết thúc, và có thể tiếp tục chạy ở 1 thời điểm khác.
function* name([param[, param[, ... param]]]) { statements }
- name: tên hàm.
- param: tham số đầu vào của hàm, tối đa 255 tham số.
- statements: nội dung của hàm.
Hàm sẽ không được thực thi ngay sau khi gọi, mà thay vào đó generator function trả về iterator, giống như con trỏ trong vòng lặp.
Sau khi hàm next() của iterator được gọi, generator function sẽ thực thi hàm cho đến khi gặp từ khóa yield đầu tiên. yield sẽ trả về giá trị cho iterator, generator function kết thúc cho đến khi hết giá trị để yield.
Nói thì dông dài, ví dụ sau sẽ dễ hiểu hơn. Hàm sau có tác dụng tạo ra ID tăng dần, mỗi khi hàm next được gọi.
function* id_maker(){ var index = 0; while(index < 3) yield index++; } var gen = id_maker(); console.log(gen.next().value); // 0 console.log(gen.next().value); // 1 console.log(gen.next().value); // 2 console.log(gen.next().value); // undefined
yield sẽ được gọi 3 lần trong vòng lặp for, do đó khi gọi đến lần thứ 4 thì log sẽ trả về undefined.
Ở ví dụ trên, gen.next() sẽ trả về một object có 2 tham số là value và done. Kiểm tra có còn next() được nữa hay không thì chỉ cần kiểm tra giá trị done
console.log(gen.next()); // { value: 0, done: false }
yield chỉ có thể return về giá trị, để return về 1 hàm, ta sử dụng yield*
function* anotherGenerator(i) { yield i + 1; yield i + 2; yield i + 3; } function* generator(i){ yield i; yield* anotherGenerator(i); yield i + 10; } var gen = generator(10); console.log(gen.next().value); // 10 console.log(gen.next().value); // 11 console.log(gen.next().value); // 12 console.log(gen.next().value); // 13 console.log(gen.next().value); // 20
Generator function là một trong những tính năng cực kì hữu ích trong ES6. Nodejs có module co và framework koa (được xem là next generator framework for nodejs) tận dụng rất tốt chức năng này.
yield còn dùng để khử callback phức tạp của Javascript, khử promise - hiện còn làm nhiều bạn lúng túng khi mới bắt đầu với nodejs.
-
Từ bản nodejs 0.12 trở lên đã được hỗ trợ chức năng generator function, với node v0.12 phải có tham số --harmony để có thể sử dụng yield/function*, còn node 4.0 trở lên thì không cần.
node --harmony ./app.js
Bài viết được viết tại blog của mình: https://blog.duyetdev.com/2016/02/generator-function-javascript.html
- Write "Synchronous" Node.js Code with ES6 Generators
- function* - Mozilla Developer Network
- Callback Hell
- ECMAScript 2015 features
- function* và yield trong Javascript generator function
Happy coding :)