coroutine

Hiển Thị Bản Đã Lỗi Thời

*Nội dung này được dịch bằng AI (Beta) và có thể có lỗi. Để xem trang này bằng tiếng Anh, hãy nhấp vào đây.

Một coroutine được sử dụng để thực hiện nhiều nhiệm vụ cùng một lúc từ trong cùng một kịch bản.Các nhiệm vụ như vậy có thể bao gồm sản xuất giá trị từ đầu vào hoặc thực hiện công việc trên một subroutine khi giải quyết một vấn đề lớn hơn.Một nhiệm vụ thậm chí không cần phải có điểm kết thúc được xác định, nhưng nó cần phải xác định các thời điểm cụ thể mà nó phát (tạm dừng) để cho phép các thứ khác được thực hiện.

Sử dụng Coroutines

Một coroutine mới có thể được tạo bằng cách cung cấp một chức năng cho coroutine.create().Một khi đã tạo, một coroutine không bắt đầu chạy cho đến khi cuộc gọi đầu tiên đến coroutine.resume() mà truyền các tham số cho chức năng.Cuộc gọi này trả về khi chức năng dừng lại hoặc gọi coroutine.yield() hoặc, khi điều này xảy ra, coroutine.resume() trả về các giá trị được trả bởi chức năng, các giá trị được gửi đến coroutine.yield() hoặc một thông tin nhắnlỗi.Nếu xảy ra lỗi, giá trị trả lại thứ hai là lỗi được ném.


local function task(...)
-- Chức năng này có thể làm một số công việc trong một lúc rồi sau đó cho ra một số giá trị
coroutine.yield("first") -- Sẽ được trả lại bởi coroutine.resume()
-- Chức năng tiếp tục một khi nó được khởi động lại
return "second"
end
local taskCoro = coroutine.create(task)
-- Gọi lại lần đầu tiên, chạy chức năng từ đầu
local success, result = coroutine.resume(taskCoro, ...)
print(success, result) --> true, trước tiên (nhiệm vụ gọi coroutine.yield())
-- Tiếp tục chạy chức năng cho đến khi nó hiển thị hoặc dừng lại
success, result = coroutine.resume(taskCoro)
print(success, result) --> true, second (task halted because it returned "second")

Trong suốt cuộc sống của coroutine, bạn có thể gọi coroutine.status() để kiểm tra tình trạng tháicủa nó:


<th>Ý nghĩa</th>
</tr>
</thead>
<tbody>
<tr>
<td><b>bị treo</b></td>
<td>Hàng đợi đang chờ được tiếp tục. Các hàng đợi bắt đầu trong trạng thái này và nhập vào khi chức năng của chúng gọi <code>coroutine.yield()</code>.</td>
</tr>
<tr>
<td><b>chạy</b></td>
<td>Coroutine đang chạy ngay bây giờ.</td>
</tr>
<tr>
<td><b>bình thường</b></td>
<td>Coroutine đang chờ đợi sản phẩm của một coroutine khác; theo cách khác, nó đã khởi động lại một coroutine khác.</td>
</tr>
<tr>
<td><b>chết</b></td>
<td>Chức năng đã dừng lại (trả về hoặc ném một lỗi). Coroutine không thể được sử dụng tiếp theo.</td>
</tr>
</tbody>
Tình trạng

Bọc lại Coroutines

Khi làm việc với các coroutine, bạn cũng có thể bỏ qua việc sử dụng đối tượng coroutine và thay vào đó sử dụng chức năng bọc.Một chức năng bọc như vậy sẽ tiếp tục một coroutine cụ thể khi nó được gọi và sẽ trả lại chỉ các giá trị được trả.Bạn có thể làm điều này bằng cách sử dụng coroutine.wrap() :


-- Tạo coroutine và trả về một chức năng bọc lại nó khởi động lại
local f = coroutine.wrap(task)
-- Tiếp tục cuộc gọi coroutine như thể chúng ta đã gọi coroutine.resume()
local result = f()
-- Nếu xảy ra lỗi, nó sẽ được nâng lên ở đây!
-- This differs from coroutine.resume() which acts similar to pcall()

Giá trị đầu tiên được trả về từ coroutine.resume() mô tả xem một coroutine có chạy mà không có lỗi hay không.Tuy nhiên, chức năng được trả về bởi coroutine.wrap() sẽ không làm điều này: thay vào đó, chúng trực tiếp trả lại các giá trị được trả hoặc được chuyển đến coroutine.yield(), nếu có.Nếu một lỗi đã xảy ra trong khi chạy chức năng coroutine, lỗi được nâng lên trong cuộc gọi của chức năng trả về.

Ví dụ mô hình sản xuất

Hãy tưởng tượng một nhiệm vụ sản xuất lặp lại của một từ: mỗi khi nó sản xuất một lặp lại, lần tiếp theo sẽ sản xuất thêm một lần.Ví dụ, cung cấp Hello sẽ sản xuất Hello , HelloHello , HelloHelloHello , v.v.Để làm điều này, bạn có thể định nghĩa repeatThis() :


-- Chức năng này lặp lại một từ mỗi khi coroutine được khởi động lại
local function repeatThis(word)
local repetition = ""
while true do
-- Lặp lại một lần rồi lấy kết quả
repetition = repetition .. word
coroutine.yield(repetition)
end
end

Để chạy chức năng này như một coroutine, bạn có thể sử dụng coroutine.create() theo sau bởi nhiều cuộc gọi đến coroutine.resume() :


local repetitionCoro = coroutine.create(repeatThis)
print(coroutine.resume(repetitionCoro, "Hello")) -- đúng, Xin chào
print(coroutine.resume(repetitionCoro)) -- đúng, HelloHello
print(coroutine.resume(repetitionCoro)) -- true, HelloHelloHello

Đối với chức năng sản xuất này, bạn cũng có thể sử dụng coroutine.wrap() để có được một chức năng sản xuất giá trị:


local f = coroutine.wrap(repeatThis)
print(f("Hello")) -- Xin chào
print(f()) -- Xin chàoHello
print(f()) -- HelloHelloHello

Tóm Tắt

Chức Năng

Chức Năng

close

Đóng và đặt coroutine được cung cấp trong trạng thái chết.Chức năng này trả về true trừ khi coroutine ở trong trạng thái lỗi, trong đó nó trả về false và tin nhắn lỗi.Một coroutine đang chạy hiện tại không thể được đóng.Một coroutine không thể được tiếp tục sau khi nó được đóng.

Tham Số

Lợi Nhuận

true trừ khi coroutine đang đóng ở trạng thái lỗi.

Variant<string, ()>

Tin nhắc tin nhắn, nếu có.

create

Tạo một coroutine mới, với thân f. f phải là chức năng Luau.

Tham Số

Lợi Nhuận

isyieldable

Trả về true nếu coroutine chức năng này được gọi trong có thể an toàn sản xuất.Từ bỏ một coroutine bên trong metamethods hoặc chức năng C bị cấm, với ngoại lệ của pcallxpcall .

Lợi Nhuận

Liệu có hay không có thể thực hiện coroutine một cách an toàn tại thời điểm này.

resume

Bắt đầu hoặc tiếp tục thực hiện coroutine co .Lần đầu tiên bạn tiếp tục một coroutine, nó bắt đầu chạy cơ thâncủa nó.Các giá trị ... được truyền làm tham số cho chức năng cơ thể.Nếu coroutine đã được trả, hãy khởi động lại nó; các giá trị ... được truyền là kết quả từ yield.Nếu coroutine chạy mà không có lỗi, tiếp tục trả về true cộng bất kỳ giá trị nào được truyền đến để lấy (nếu coroutine lấy) hoặc bất kỳ giá trị nào được trả bởi chức năng cơ thể (nếu coroutine kết thúc).Nếu có bất kỳ lỗi nào, tiếp tục trả về sai lầm cộng với thông tin nhắnlỗi.

Tham Số

...: Variant

Lợi Nhuận

running

Trả lại coroutine đang chạy.

Lợi Nhuận

status

Trả lại tình trạng của coroutine co, dưới dạng một chuỗi: 'running', nếu coroutine đang chạy (đó là, nó gọi tình trạng thái); ' suspended', nếu coroutine bị treo trong một cuộc gọi để lấy, hoặc nếu nó chưa bắt đầu chạy; 'normal' nếu coroutine đang hoạt động nhưng chưa bắt đầu chạy (đó là, nó đã khởi động lại một coroutine khác); và 'dead' nếu coroutine đã kết thúc chức năng cơ thể của nó, hoặc nếu nó đã dừng lại với một lỗi.

Tham Số

Lợi Nhuận

Tạo một coroutine mới, với thân f.f phải là chức năng Luau.Trả về một chức năng khôi phục lại chuỗi hành động mỗi khi nó được gọi.Bất kỳ tham số nào được truyền cho chức năng hành xử như tham số bổ sung để tiếp tục.Trả về các giá trị tương tự được trả bởi tiếp tục, ngoại trừ boolean đầu tiên.Trong trường hợp lỗi, lan truyền lỗi.

Tham Số

Lợi Nhuận

yield

Tuple<Variant>

Tạm dừng thực thi của coroutine gọi.Bất kỳ tham số nào để trả về được chuyển là kết quả bổ sung để tiếp tục.Từ bỏ một coroutine bên trong metamethods hoặc chức năng C bị cấm, với ngoại lệ của pcallxpcall .

Tham Số

...: Tuple

Lợi Nhuận

Tuple<Variant>