ComfyUI Extension: AsyncOutput

Authored by teddy1565

Created

Updated

0 stars

Run ComfyUI workflows without the setup

No installs, no CUDA version roulette, no GPU sitting idle on your bill. Bring a workflow and run it in the browser.

Simple collect all batch output, then convert to a string list, like ECMAScript Promise.all

README

��# ComfyUI-AsyncOutput

Simple Source Code

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

const tasks_queue: Array<Promise<string>> = [];
for (let i = 0; i < n; i++) {
    const task = new Promise<string>((resolve, reject) => {
        /* Your jobs, just a mock, */
    });
    tasks_queue.push(task);
}

/*
results will be an Array<string>
*/
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

const string_list = ["abc", "edf", "jqk"];
const str = string_list.join("<your_input>");

AsyncOutputCollect(Collection)

const collect_list = [];

for (let i = 0; i < n; i++) {
    const task = new Promise();
    collect_list.push(task);
}

AsyncOutputEmitter(Conditions)

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)


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);
    }
});

Run ComfyUI workflows without the setup

No installs, no CUDA version roulette, no GPU sitting idle on your bill. Bring a workflow and run it in the browser.

Learn more