2017-02-17 42 views

Trả lời

10

Trước tiên, tôi sẽ bắt đầu bằng cách nói rằng Máy phát điện là một chủ đề hơi phức tạp, do đó, việc đưa ra tổng quan hoàn chỉnh ở đây sẽ không thể thực hiện được. Để biết thêm thông tin tôi rất muốn giới thiệu loạt bài của You Don't Know JS của Kyle Simpson. Cuốn sách 5 (Async & Performance) có một cuộc thảo luận tuyệt vời về các ins and outs của máy phát điện.

Đến ví dụ cụ thể mà bạn đã cung cấp!

Trước tiên, mã bạn đã viết trong ví dụ sẽ hiển thị không có sự khác biệt nhưng chỉ khi nó chạy đúng. Dưới đây là ví dụ:

function* foo() { 
    yield 123; 
} 

function* bar() { 
    return yield 123; 
} 

var f = foo(); 
var b = bar(); 

f.next(); // {value: 123, done: false} 
f.next(); // {value: undefined, done: true} 
b.next(); // {value: 123, done: false} 
b.next(); // {value: undefined, done: true} 

Như bạn có thể thấy, tôi không gọi máy phát điện như chức năng bình thường. Bản thân trình tạo sẽ trả về đối tượng máy phát (một dạng của trình lặp). Chúng tôi lưu trữ trình lặp đó trong một biến và sử dụng hàm .next() để chuyển tiếp trình lặp tới bước tiếp theo (một từ khóa yield hoặc return).

Từ khóa yield cho phép chúng tôi chuyển giá trị vào trình tạo và đây là nơi các ví dụ của bạn sẽ chạy khác nhau. Đây là những gì mà sẽ trông như thế:

function* foo() { 
    yield 123; 
} 

function* bar() { 
    return yield 123; 
} 

var f = foo(); 
var b = bar(); 

// Start the generator and advance to the first `yield` 
f.next(); // {value: 123, done: false} 
b.next(); // {value: 123, done: false} 

/** Now that I'm at a `yield` statement I can pass a value into the `yield` 
* keyword. There aren't any more `yield` statements in either function, 
* so .next() will look for a return statement or return undefined if one 
* doesn't exist. Like so: 
*/ 
f.next(2); // {value: undefined, done: true} 
b.next(2); // {value: 2, done: true} 

ý rằng foo() sẽ trở lại undefined như một giá trị, trong khi bar() trả về số 2. Điều này là do giá trị chúng ta đang đi vào .next() cuộc gọi được gửi đến từ khóa return và đặt làm giá trị trả lại. foo() không có tuyên bố trả về rõ ràng, vì vậy bạn sẽ nhận được hành vi mặc định undefined.

Hy vọng rằng điều này sẽ hữu ích!

6

Sự khác biệt là giá trị kết quả của các cuộc gọi tiếp lần cuối:

function* fooA() { 
    yield 123 
}; 
var a = fooA(); 
console.log(a.next(1)); // {done:false, value:123} 
console.log(a.next(2)); // {done:true, value:undefined} 

function* fooB() { 
    return 40 + (yield 123) 
}; 
var b = fooB(); 
console.log(b.next(1)); // {done:false, value:123} 
console.log(b.next(2)); // {done:true, value:42} 

Hầu hết các máy phát điện không cần một giá trị return, mục đích của họ là thế hệ của một dòng giá trị như một tác dụng phụ khi họ đang chạy. Tất cả các trình vòng lặp thuộc loại này, nếu chúng được chạy bởi một vòng lặp for of thì kết quả chỉ biểu thị kết thúc, nhưng giá trị sẽ bị hủy bỏ.

Tuy nhiên, cũng có các máy phát có giá trị kết quả là quan trọng, ví dụ: khi chúng được sử dụng như một công cụ để mô tả các quá trình không đồng bộ (trong một polyfill cho async/await cú pháp lời hứa, hoặc cũng nhiều thứ khác như CSP). Bạn cũng nhận được giá trị ed return khi sử dụng yield* trên một lần lặp.

Trong mọi trường hợp, return yield cùng nhau không có vẻ rất hữu ích.

Các vấn đề liên quan