Chuyển tới nội dung chính

Biến, Input và Bộ nhớ

Microbe Studio cho bạn bốn chỗ khác nhau để giữ một giá trị, và chúng khác nhau đúng một điều: giá trị sống bao lâu, và ai nhìn thấy nó. Chọn nhầm là nguyên nhân phổ biến nhất của "bộ đếm của tôi bị reset" và "hai instance của tôi giành nhau một giá trị".

Trang này vẽ bản đồ cả bốn.

Mục đích

Dùng trang này để quyết định, cho bất kỳ mẩu dữ liệu nào:

  • Nó nên là biến hay mục bộ nhớ?
  • Nó có cần sống qua lần chạy? Qua khởi động lại app? Instance khác có cần thấy nó?
  • Người vận hành có nên gõ nó vào trước khi chạy?

Bốn ngôi nhà, nhìn nhanh

Ngôi nhàSống trongAi thấyDùng điển hình
Biến flow (scope: flow)Một lần chạyChỉ lần chạy đóBộ đếm, trạng thái vòng lặp, kết quả OCR
Biến Instance (scope: global)Mãi mãi, qua khởi động lạiMọi flow trên một instance"Instance này đăng nhập tài khoản nào"
Runtime MemoryTTL theo từng mục, bạn chọnTùy scope bộ nhớ (dưới đây)"Đừng đụng mục tiêu này thêm 15 phút"
Flow Input ParameterMột lần chạy, cấp lúc khởi độngLần chạy đó"Chuyến này xử lý bao nhiêu mục"

Biến flow

Biến flow được khai trong hộp thoại Variables của flow với đường dẫn (vars.gem_farmed_trip), kiểu, và giá trị mặc định tùy chọn.

Các kiểu

Các kiểu khai báo được:

string, number, boolean, point, rect, object, array, null

Mỗi kiểu trừ null có thêm biến thể nullable viết với ? cuối — number?, string?, v.v. Biến nullable được phép giữ null; biến không nullable thì không, và giá trị vi phạm khai báo sẽ từ chối khởi động lần chạy với TYPE_MISMATCH.

Khởi tạo thế nào

Ở đầu mỗi lần chạy, theo đúng thứ tự:

  1. Mọi biến khai báo được đặt null.
  2. defaultValue của khai báo được áp nếu có.
  3. initialValues của flow được áp.
  4. Mỗi giá trị được kiểm với kiểu khai báo.
  5. Bất kỳ giá trị nào vi phạm, lần chạy không khởi động.

Thứ tự này nghĩa là mặc định luôn thắng null, và initial value luôn thắng mặc định.

Đọc và ghi

Tham chiếu biến trong hầu hết ô chữ với một trong hai cú pháp — cả hai được chấp nhận và y hệt nhau:

{{gem_farmed_trip}}
${gem_farmed_trip}

Ghi biến bằng node Variable, chứa danh sách các dòng gán. Mỗi dòng có đích và thao tác:

Thao tácHiệu ứng
setĐịnh giá biểu thức và lưu kết quả
clearTrả biến về mặc định khai báo
deleteGỡ biến khỏi ngữ cảnh
logGhi giá trị hiện tại vào log lần chạy (không đổi)

Dòng set còn mang được expire after (ttlSeconds, tối đa một năm). Hết hạn thì giá trị hồi về mặc định của khai báo thay vì biến mất.

Khuôn mẫu bộ đếm

Cặp hai node hữu dụng nhất sản phẩm:

  1. Node Variable: vars.items_done = {{items_done}} + 1
  2. Node If: {{items_done}} >= {{max_per_trip}}

Cặp đó cho bạn "làm N lần, N cấp theo lần chạy" mà không cần node vòng lặp, và nó sống sót qua rẽ nhánh — điều một bộ đếm vòng lặp không làm được.

Biến Instance

Đặt scope: global trên khai báo — nhãn Instance trong UI — thay đổi hoàn toàn nơi lưu:

  • Giá trị bền qua các lần chạy và qua khởi động lại app.
  • Nó được chia sẻ bởi mọi flow chạy trên instance đó.
  • cách ly giữa các instance: instance A và B mỗi bên một bản.

Dùng cho sự thật về thiết bị, không phải về lần chạy. "Đăng nhập tài khoản nào", "instance này đã setup lần đầu chưa", "instance này ở server nào".

Biến Instance rất lì

Vì sống qua khởi động lại, một biến Instance cũ kỹ sẽ âm thầm ảnh hưởng các lần chạy nhiều ngày sau. Cho chúng một đường reset chủ đích — một dòng clear trong flow setup — thay vì mặc định là khởi đầu sạch.

Flow Input Parameter

Đánh dấu khai báo là input và nó thành Flow Input Parameter: vẫn là biến thường bên trong flow, nhưng còn được đưa ra nhập liệu trước lần chạy.

  • Người vận hành điền trên form Run Condition của Dashboard.
  • Đánh dấu required chặn lần chạy nếu bỏ trống.
  • Node Sub Flow gắn được biểu thức của cha vào input của con — truyền đối số thực thụ.

Đây là thứ biến flow thành hàm tái dùng:

Con khai thứ nó cần; cha cấp tại điểm gọi. Con không biết gì về bên gọi, nên cùng một con chạy được từ mục Queue, từ Lịch, hay từ ba cha khác nhau.

Runtime Memory

Biến trả lời "điều gì đúng ngay lúc này trong lần chạy này". Runtime Memory trả lời câu khác: "tôi đã xử lý thứ này chưa, và gần đây cỡ nào?"

Nó là kho key/value đa mục với TTL theo từng mục, được node Runtime Memory ghi và node Memory Match truy vấn.

Bốn scope bộ nhớ

Đây là phần đáng học cho chính xác:

ScopeSống qua kết thúc lần chạySống qua khởi động lại appChia sẻ giữa instance
runKhôngKhôngKhông
sessionKhông — một lần mở appKhông — riêng từng instance
persistKhông — riêng từng instance
shared — scope liên-instance duy nhất
  • run sống trên ngữ cảnh thực thi của lần chạy. Biến mất cùng lần chạy.
  • session nghĩa là "lần mở app này". Mở mới bắt đầu rỗng.
  • persist lưu SQLite, an toàn qua khởi động lại.
  • shared là opt-in chủ đích duy nhất cho phối hợp liên-instance. Mọi scope khác đặt namespace mục theo instance, nên instance A không bao giờ đọc/đè bộ nhớ của instance B.
shared chia sẻ thật sự

Mười instance ghi cùng một khóa trong scope shared sẽ đè lên nhau. Chỉ dùng khi phối hợp liên-instance chính là mục đích — ví dụ danh sách "mục tiêu này có người nhận" toàn cục. Thứ gì theo thiết bị, dùng persist.

Khuôn mẫu chốt-chặn-cooldown

Cách dùng kinh điển của Runtime Memory: đừng xử lý lại thứ vừa xử lý gần đây.

Memory Match so ứng viên với mọi mục còn sống bằng biểu thức có thể tham chiếu mục đang xét là {{item.<trường>}}:

(abs({{current_x}} - {{item.x_coordinate}}) <= 1) && (abs({{current_y}} - {{item.y_coordinate}}) <= 1)

Đọc là "có mục đã nhớ nào trong vòng một ô quanh chỗ tôi đứng không?" — so khớp dung sai, không phải bằng tuyệt đối, đúng thứ dữ liệu màn hình thật cần.

Vì mục mang TTL 900 giây, chốt chặn tự hết hạn sau 15 phút. Không gì phải dọn.

Các thao tác bộ nhớ

Thao tácLàm gìCần key
rememberThêm mục (key trống tự sinh)Không
forgetGỡ một mục theo key
clearDọn cả bộ nhớKhông
countGhi số mục còn sống vào biếnKhông

Chọn thế nào: bảng quyết định

Bạn muốn…Dùng
Đếm lượt trong một lần chạyBiến flow
Truyền một con số trước khi chạyFlow Input Parameter
Nhớ giả lập này dùng tài khoản nàoBiến Instance
Tránh ghé lại mục tiêu trong 15 phútRuntime Memory, persist, TTL
Chỉ tránh ghé lại trong lần chạy nàyRuntime Memory, run
Cho mọi instance né một danh sách chungRuntime Memory, shared

Best practices

  • Khai báo mọi biến bạn dùng. Tham chiếu chưa khai hỏng lúc khởi động thay vì giữa chừng — đó là kiểu hỏng bạn muốn.
  • Cho bộ đếm mặc định 0, không phải null. null + 1 không phải con số.
  • Dùng number? cho mọi thứ OCR ghi. Lần đọc hỏng không sinh giá trị, và khai báo không-nullable sẽ từ chối nó.
  • Ưu tiên TTL hơn dọn tay. Mục tự hết hạn không thể rò rỉ.
  • Đặt tên input theo quyết định nó điều khiểnmax_per_trip, không phải n.
  • Reset bộ đếm chuyến ở ranh giới tự nhiên, không phải đầu vòng lặp. Trong automation tham chiếu, bộ đếm reset khi flow quay về căn cứ — điểm "một chuyến" thực sự kết thúc.

Ghi chú hiệu năng

  • Đọc biến và định giá biểu thức nằm trong bộ nhớ, gần như miễn phí. Đừng né biến vì lý do hiệu năng.
  • Thao tác bộ nhớ persistshared chạm SQLite. Nhanh, nhưng là I/O — tránh đặt remember trong vòng lặp trong siết chạy trăm lần mỗi giây.
  • count quét các mục sống của bộ nhớ. Bộ nhớ lớn thì tự duy trì một biến đếm sẽ hơn.

Ghi chú bộ nhớ

  • Mỗi session mang bản sao riêng của mọi biến flow. Một flow chạy trên 10 instance nghĩa là 10 bộ biến độc lập.
  • Runtime Memory scope run giữ trên ngữ cảnh thực thi và giải phóng khi lần chạy kết thúc.
  • Scope session lưu trong CSDL chung dưới token theo lần mở app; app thu hồi các hàng của lần mở trước lúc khởi động, nên nó không phình vô hạn.
  • Mục bộ nhớ hết hạn theo thời gian tuyệt đối, nên mục ghi TTL 900 giây vẫn hết hạn sau khởi động lại — thời hạn được lưu, không phải đếm ngược trong RAM.

Lỗi thường gặp

LỗiTriệu chứngCách sửa
Bộ đếm khai không mặc địnhPhép cộng chẳng ra gìMặc định 0
Biến không-nullable gắn kết quả OCRLần chạy từ chối TYPE_MISMATCHKhai number? / string?
Dùng bộ nhớ shared cho trạng thái theo máyInstance đè lên nhauDùng persist
Mong session sống qua khởi động lạiRỗng sau mở lạiDùng persist
Reset bộ đếm chuyến ở đầu vòngKhông bao giờ chạm ngưỡngReset ở ranh giới chuyến
Coi biến Instance khởi đầu sạchGiá trị mốc từ nhiều ngày trướcClear tường minh trong setup

Khắc phục sự cố

Bộ đếm của tôi mãi là 1. Node Variable đang reset thay vì tăng. Kiểm biểu thức là {{x}} + 1 chứ không phải 1.

Lần chạy từ chối khởi động với TYPE_MISMATCH. Một mặc định hoặc initial value lệch kiểu khai. Thường là đích OCR nullable bị khai non-nullable.

Memory Match không bao giờ khớp. Kiểm scope trên cả hai node — remember scope run vô hình với match đọc persist. Xác nhận luôn tên trường trong biểu thức khớp trường bạn đã lưu.

Hai instance cứ né việc của nhau. Chúng chia một bộ nhớ scope shared. Chuyển sang persist để cách ly theo thiết bị.

FAQ

{{name}} khác ${name} không? Không. Cả hai được chấp nhận, hành xử y hệt. Chọn một và nhất quán.

Sub Flow đổi được biến của cha không? Con nhận input đã gắn làm biến cục bộ của nó. Truyền kết quả ngược bằng trạng thái kết thúc của con, hoặc một scope bộ nhớ chia sẻ.

Biến hết TTL thì thành gì? Hồi về giá trị mặc định khai báo — không thành null trừ khi mặc định là vậy.

Biến Instance có đồng bộ giữa các máy tính? Không. Cục bộ với instance trên bản cài đó.

Trang liên quan