register("hello", function (Context $context) { // You don't have to, but you should return a promise from your // commands. return new Promise(function (callable $resolve) use ($context) { Loop::addTimer(1, function () use ($context, $resolve) { $resolve("Hello, {$context->name}"); }); }); }); // Note how the arguments can be unwrapped. You can still add Context as // an argument to get the full context. Values will be cast to match the // type, so keep this in mind when feeding strings like 'false' into a // boolean argument. It is also a good idea to make the arguments nullable. $commands->register("hello2", function (?string $name, ?string $phrase, ?string $missing) { // Just returning the value works just fine! return "Greetings, {$name}. {$phrase} to you too!"; }); // Create the bus $bus = new CommandBus($commands); // And execute some commands! $bus->execute('hello', ['name'=>'Bob']) ->then(function ($result) { var_dump($result); } ); $bus->execute('hello2', ['name'=>'Bob','phrase'=>'Good day']) ->then(function ($result) { var_dump($result); } );