Đang mở...

Iterator và Generator trong Javascript

Iterables và iterators trong ES6 Từ trước đến nay để lặp qua các phần tử của một mảng thì chúng ta sử dụng vòng lặp. Ví dụ bạn muốn lặp...
Danh mục Blog
20/03/2023
Iterator và Generator trong Javascript

Iterables và iterators trong ES6

Từ trước đến nay để lặp qua các phần tử của một mảng thì chúng ta sử dụng vòng lặp. Ví dụ bạn muốn lặp qua từng phần tử và có thể dừng ở một phần tử bất kì, điều này hoàn toàn làm được bằng vòng lặp nhưng không được hay và tốn chi phí tính toán. Vì vậy trong ES6 cung cấp cho chúng ta iterators.

Cùng tìm hiểu nó hoạt động như thế nào nhé!

Iterators là gì?

Iterators là một bộ duyệt dùng để duyệt qua một mảng hoặc một collection mà qua mỗi lần duyệt sẽ ghi lại vị trí đã duyệt để từ đó có thể biết và lấy vị trí tiếp theo.

Trong Javascript thì iterators có chung cấp phương thức next() và phương thức này sẽ return về phần tử kết tiếp, đồng thời ghi nhận luôn phần tử đã lặp là phần tử next(). Phương thức next() sẽ return về một Object gồm hai thuộc tính là value và done.

let arr = ['a', 'b', 'c'];

var iterator = arr[Symbol.iterator]();

console.log(iterator.next());   // Object {value: 'a', done: false}
console.log(iterator.next());   // Object {value: 'b', done: false}
console.log(iterator.next());   // Object {value: 'c', done: false}
console.log(iterator.next());   // Object {value: 'undefined', done: true}

Giá trị lần next() cuối cùng là một giá trị undefined và key done của nó sẽ là true.

Đoạn code trên tại sao lại có Symbol.iterator? Symbol.iterator là gì? Tìm hiểu qua một chút về Iterator Protocol và Iterable nhé!

Iterable

Iterable là khả năng cho phép các đối tượng trong Javascript sử dụng các kỹ thuật xử lý dữ liệu như for of loop, toán tử ba chấm …

Với ES6 thì các đối tượng như Array, Object, Map, WeakMap, Set, WeakSet đều là đối tượng Iterable.

Iterator protocol

Iterator Protocol chẳng qua chỉ là các giao thức (method) xử lý một đối tượng có đánh dấu vị trí đã duyệt, vì vậy với các đối tượng thông thường sẽ không sử dụng được nên ta phải sử dụng Symbol.iterator để chuyển đôi.

let arr = ['a', 'b', 'c'];

var iterator = arr[Symbol.iterator]();

console.log(iterator.next());   // Object {value: 'a', done: false}
console.log(iterator.next());   // Object {value: 'b', done: false}
console.log(iterator.next());   // Object {value: 'c', done: false}
console.log(iterator.next());   // Object {value: 'undefined', done: true}
Iterable
  • Data consumers: Các phương thức – hành động của Iterator, đây cũng chính là Iterator Protocol.
  • Interface: Interface là một lớp trung gian kế thừa tất cả các Data consummers, đây chính là Iterable. Và vì trong Javascript không tồn tại Interface nên ta sử dụng Symbol.iterator để chuyển đổi.
  • Data Resources: Các đối tượng dữ liệu trong Javascript muốn chuyển sang Iterable.

Tóm lại:

  • Như vậy Iterator là những toán tử có khả năng liệt kê các phần tử trong các đối tượng tập hợp như Array, Object, Map, Set, WeakMap, WeakSet.
  • Các đối tượng muốn sử dụng được Iterator Protocol thì phải thông qua Interface. Thông thường thì các đối tượng như array, collection đề đã có sẵn iterable.
  • Với phương thức next() thì bạn phải thực hiện thao tác chuyển đổi thông qua Symbol.iterator.

Genarator trong ES6

Generator là gì?

  • Generator là object được trả về từ generator function.
  • Generator không thể được tạo ra trực tiếp. Bạn phải tạo ra 1 generator function sau đó gọi hàm này thì generator mới được tạo ra.

Cú pháp

function* generateId() {
	yield 1;
	console.log('Continue to run');
	yield 2;
	console.log('Resume');
	return 3;
}
const newId = generateId();
newId.next(); // { value: 1, done: false }
newId.next(); // { value: 2, done: false }
newId.next(); // { value: 3, done: true }

Đặc điểm của 1 Generator Function

  • Hàm có thể dừng giữa chừng và tiếp tục sau.
  • Mỗi lần gọi, hàm sẽ được thực thi cho đến khi gặp lệnh yield hoặc return.

Generator có 3 hàm:

  • next() : Tiếp tục thực thi hàm cho đến khi gặp yield / return // { value: 2, done: true/false }
  • return() : Dừng Generator function và return kết quả // { value: 3, done: true }
  • throw() : Dừng generator function và trả về lỗi // { value: undefined, done: true }

Ví dụ Fibonanci với generator

function* generateFibonaci() {
	let prev = 0;
	let curr = 1;
	while (true) {
		yield curr;
		// Calculate the next number
		const next = prev + curr;
		prev = curr;
		curr = next;
	}
}
const fibo = generateFibonaci();
console.log(fibo.next()); // { value: 1, done: false }
console.log(fibo.next()); // { value: 1, done: false }
console.log(fibo.next()); // { value: 2, done: false }
console.log(fibo.next()); // { value: 3, done: false }
console.log(fibo.next()); // { value: 5, done: false }

Vitamindev

Chia sẻ bài viết này

Leave a Reply Câu trả lời

Địa chỉ email của bạn sẽ không được công bố.

Các nội dung liên quan

Xem các nội dung liên quan

26/06/2023
Sử dụng Bucket4j để thực hiện rate limiting trong Java
1. Giới thiệu Blog này, Chúng ta sẽ tìm hiểu về rate limiting và lợi ích của việc sử dụng Bucket4j cho rate limiting trong ứng dụng Java. Rate Limiting...
13/06/2023
Tìm hiểu về Gitlab CI/CD
I. Tổng quan GitLab CI là một phần của GitLab, là một hệ thống quản lý mã nguồn Git dựa trên web và một công cụ liên kết liền mạch để...
06/06/2023
Tìm hiểu về Lists và Keys trong React
Đã bao giờ bạn đặt câu hỏi rằng tại sao lại cần key khi map 1 mảng? Tôi chắc chắn bạn đã gặp cảnh báo này: Chỉ cần thêm thuộc...
19/05/2023
Hướng dẫn dùng Jquery Ajax submit form và gọi REST API
AJAX đại diện cho Asynchronous JavaScript And XML bằng cách sử dụng đối tượng XMLHttpRequest để tương tác với máy chủ (server).