2013-07-07 30 views
15

Node.js hiện có các trình tạo.Cố gắng hiểu máy phát/năng suất trong node.js - điều gì thực thi chức năng không đồng bộ?

Sự hiểu biết của tôi là máy phát có thể được sử dụng để viết mã có vẻ tuyến tính hơn và tránh địa ngục gọi lại và kim tự tháp mã hóa kiểu doom.

Vì vậy, đến thời điểm này, sự hiểu biết của tôi là bên trong một máy phát điện, mã thực hiện cho đến khi nó đạt đến một tuyên bố "lợi nhuận". Việc thực thi chức năng của máy phát điện bị treo tại thời điểm này. Câu lệnh yield chỉ định giá trị trả về có thể là một hàm. Thông thường, điều này sẽ là một chức năng I/O chặn - một trong những thường sẽ cần phải được thực hiện không đồng bộ.

Chức năng trả về của sản phẩm được trả về bất kỳ thứ gì gọi là trình tạo.

Câu hỏi của tôi là, điều gì sẽ xảy ra vào thời điểm này? Chính xác những gì thực thi chức năng I/O chặn mà lợi nhuận trả về?

Để viết mã máy phát/mã sản xuất có vẻ là tuyến tính, cần phải có một loại hàm cụ thể gọi là trình tạo, một hàm lặp qua trình tạo và thực thi từng hàm asynch được trả về bởi năng suất và trả về kết quả của chức năng asynch trở lại vào máy phát điện?

Tôi vẫn chưa rõ chính xác cách hàm asynch được trả về bởi lợi nhuận được thực thi. Nếu nó được thực thi bởi hàm gọi trình tạo, nó có được thực hiện không đồng bộ không? Tôi đoán như vậy bởi vì để làm khác sẽ dẫn đến hành vi chặn.

Để tóm tắt câu hỏi của tôi:

  1. Để viết "tuyến tính" mã asynch với máy phát điện, là nó cần thiết để có được một chức năng gọi điện thoại mà lặp trên các máy phát điện, thực hiện chức năng mang lại như callbacks và gửi lại kết quả của cuộc gọi lại vào máy phát điện?
  2. Nếu câu trả lời cho câu hỏi 1 là có, chính xác các hàm được thực hiện được thực hiện như thế nào - không đồng bộ?

Có ai có thể cung cấp tổng quan/tóm tắt tốt hơn về toàn bộ quá trình hoạt động không?

+0

Điều này có thể giúp phần nào, cũng liên kết đến mã trong bài đăng: http: //bjouhier.wordpress.com/2013/06/01/bring-asyncawait-to-life-in-javascript/ –

+0

Bạn có thể muốn xem https://github.com/loveencounterflow/coffy-script có phần giới thiệu từng bước dài lập trình không đồng bộ với máy phát. – flow

Trả lời

10

Khi viết mã async với máy phát điện bạn đang đối phó với hai loại chức năng:

  • bình thường chức năng khai báo với function. Các chức năng này không thể sản xuất. Bạn không thể viết mã không đồng bộ theo kiểu đồng bộ với chúng vì chúng chạy để hoàn thành; bạn chỉ có thể xử lý hoàn thành không đồng bộ thông qua callbacks (trừ khi bạn gọi thêm sức mạnh như thư viện node-fibers hoặc chuyển đổi mã).
  • máy phát điện chức năng được khai báo với function*. Các chức năng này có thể lợi nhuận. Bạn có thể viết mã không đồng bộ theo kiểu đồng bộ bên trong chúng vì chúng có thể sinh lợi. Nhưng bạn cần một hàm đồng hành để tạo trình tạo, xử lý cuộc gọi lại và tiếp tục lại máy phát điện với cuộc gọi next mỗi lần gọi lại.

Có một số thư viện triển khai chức năng đồng hành. Trong hầu hết các thư viện này, hàm đồng hành xử lý một đơn function* cùng một lúc và bạn phải đặt một trình bao bọc xung quanh mọi mã function* trong mã của bạn. Thư viện thiên hà (mà tôi đã viết) là một chút đặc biệt bởi vì nó có thể xử lý function* gọi khác function* mà không có trình bao bọc trung gian. Chức năng đồng hành là một chút phức tạp bởi vì nó phải đối phó với một chồng máy phát điện.

Luồng thực thi có thể khó hiểu vì đoạn nhảy yield/next nhỏ giữa function* và hàm đồng hành của bạn. Một cách để hiểu luồng là viết một ví dụ với thư viện bạn chọn, thêm console.log câu lệnh cả trong mã của bạn và trong thư viện và chạy nó.

4

Nếu [chức năng chặn io] được thực thi bởi chức năng gọi trình phát, nó có được thực hiện không đồng bộ không? Tôi đoán như vậy bởi vì để làm khác sẽ dẫn đến hành vi chặn.

Tôi không nghĩ rằng trình tạo sẽ xử lý tác vụ không đồng bộ. Với máy phát, chỉ có một điều đang thực thi cùng một lúc - nó chỉ là một chức năng có thể ngừng thực hiện và chuyển điều khiển sang một chức năng khác. Ví dụ,

function iofunc1() { 
    console.log('iofunc1'); 
} 

function iofunc2() { 
    console.log('iofunc2'); 
} 

function* do_stuff() { 
    yield iofunc1; 
    yield iofunc2; 
    console.log('goodbye'); 
} 


var gen = do_stuff(); 
(gen.next().value)(); 
(gen.next().value)(); //This line won't begin execution until the function call on the previous line returns 
gen.next(); //continue executing do_stuff 

Nếu bạn đọc một số bài viết về phát nodejs:

  1. http://jlongster.com/2012/10/05/javascript-yield.html
  2. http://jlongster.com/A-Study-on-Solving-Callbacks-with-JavaScript-Generators
  3. http://jlongster.com/A-Closer-Look-at-Generators-Without-Promises

...tất cả họ đều sử dụng các hàm/thư viện bổ sung để thêm vào thực thi không đồng bộ.

2

1: viết "tuyến tính" mã asynch với máy phát điện, là nó cần thiết cho có được một chức năng gọi điện thoại mà lặp trên các máy phát điện, thực hiện mang lại chức năng như callbacks và trả lại kết quả của gọi lại trở lại vào máy phát điện?

Có. Hãy gọi nó là "launcher".

2: nếu câu trả lời cho câu hỏi 1 là có, chính xác cách các hàm được thực thi chính xác - không đồng bộ?

Bên trong trình tạo, bạn tạo một mảng với: hàm và tham số của hàm. Trong trình kiểm soát người gọi (launcher), bạn sử dụng fn.apply (.., gọi lại) để gọi async, đưa cuộc gọi đến "generator.next (data);" (tiếp tục) bên trong gọi lại.

chức năng async được thực hiện không đồng bộ, nhưng các máy phát điện sẽ là "dừng lại" tại điểm năng suất, cho đến khi gọi lại được gọi là (và sau đó "generator.next (dữ liệu)" được thực hiện)

lib làm việc đầy đủ và các mẫu: https://github.com/luciotato/waitfor-es6