# ComfyUI-AsyncOutput Simple Source Code ```python class AsyncOutputCollectionNode: def __init__(self): pass @classmethod def INPUT_TYPES(s): return { "required": { "incoming_input": ("STRING", { "forceInput": True }), "key_id": ("STRING", {}) }, "hidden": { "unique_id": "UNIQUE_ID" } } RETURN_TYPES = ("STRING",) RETURN_NAMES = ("passthough_output",) CATEGORY = f'{MAIN_CATEGORY}/String' FUNCTION = "collect" def collect(self, incoming_input, key_id, unique_id): global ASYNC_OUTPUT_STORAGE_DATA if key_id == "": raise Exception("ERROR: key_id property not set.") if key_id not in ASYNC_OUTPUT_STORAGE_DATA: ASYNC_OUTPUT_STORAGE_DATA[key_id] = [] ASYNC_OUTPUT_STORAGE_DATA[key_id].append(incoming_input) return (incoming_input,) @classmethod def IS_CHANGED(s, incoming_input, key_id, unique_id): return float('nan') ``` ## Intro Simple collect all batch output, then convert to a string list Like ECMAScript Promise.all ```ts const tasks_queue: Array> = []; for (let i = 0; i < n; i++) { const task = new Promise((resolve, reject) => { /* Your jobs, just a mock, */ }); tasks_queue.push(task); } /* results will be an Array */ Promise.all(tasks_queue).then((results) => { const ffmpeg_concat_input_str = results.join("\n"); // others }) ``` ## Parmeters - key_id: persistence memory dict key ## Node - String - AsyncOutputCollect(Collection) - Receive other node 'string' output, persistence memory - Output is 'string', passthrough your input - AsyncOutputEmitter(Conditions) - If conditions is true, Output Boolean, else always false. - AsyncOutputCallback(Output) - Receive Emitter Output, If true, will output dict\[key_id\], then delete dict\[key_id\] - If the received value is false, then the subsequent downstream process will be blocked directly. - (comfy_execution.graph.ExecutionBlocker(None), ) - Utils - String List To String - Convert String List to String ## Others (use JS illustrate) String List to String ```ts const string_list = ["abc", "edf", "jqk"]; const str = string_list.join(""); ``` AsyncOutputCollect(Collection) ```ts const collect_list = []; for (let i = 0; i < n; i++) { const task = new Promise(); collect_list.push(task); } ``` AsyncOutputEmitter(Conditions) ```ts const collect_list = []; const spec_task_n = 10; const mode = "exact"; const e = new EventEmitter(); function* collect_task(collect_list) { for (let i = 0; i < n; i++) { const task = new Promise(); collect_list.push(task); yield i; } } current_exec = collect_task(collect_list); let it = current_exec.next(); if (mode === "exact") { // exact mode while (it.done == false && it.value != spec_task_n) { it = current_exec.next(); e.emit("trigger_result", false); } } else if (mode === "greater_than_or_equal") { // greater_than_or_equal mode while (it.done == false && it.value <= spec_task_n) { it = current_exec.next(); e.emit("trigger_result", false); } } if (it.value == spec_tack_n) { e.emit("trigger_result", true); } ``` AsyncOutputCallback(Output) ```ts const comfy_eventloop_emitter = new EventEmitter(); e.on("trigger_result", (trigger_signal) => { if (trigger_signal === true) { const str_list = callback(); comfy_eventloop_emitter.emit("next", str_list); } }); ```