why event listener not return false

628 Views Asked by At

I have some event Samevent.
For example my event have two listener;
$result = event(new Samevent());
I must be check result;

1 case
FirstListener return false;
SecondListener return false;
dd($result) = [];

2 case
FirstListener return false;
SecondListener return true;
dd($result) = [];

3 case
FirstListener return true;
SecondListener return false;
dd($result) = [true];

4 case
FirstListener return true;
SecondListener return true;
dd($result) = [true, true];
Why happens this?? How can I fix it

2

There are 2 best solutions below

1
Keith Brink On

If you need to get the result from a function, you shouldn't use the Event system to trigger that function.

You should refactor your code in one of two ways:

1) Stop using an event, and use something like a non-queued job/interaction.

$interaction = new Interaction;
$result = $interaction->handle($vars);

dd($result);

2) Pass all the variables that are required into the event, so that your listener can do any post-event processing within the listener itself.

0
kmuenkel On

The reason everyone here is saying this is a mis-use of Events and Listeners is because their whole purpose is to be fired off asynchronously. When you trigger a listener, the content of that listener can't be guaranteed to finish executing before the thing that triggered it moves on. For that reason, they're not set up to offer a return.

Some more details about why you feel the desired logic must be from a Listener would be helpful, we may be able to guide you to a better pattern. For now though, I'd say you have a few options. In order of preference:

  1. Abstract the content of your Listener's handle() method into a brand new service class. The class that you currently feel needs to access this Listener, and the Listener itself, can then reference this Service class independently of each other.
  2. Don't fire your Listener class off an Event. Instead, instantiate it as a normal class, and then call it's handle() method directly to get your desired response.
  3. Set config(['app.queue_driver' => 'sync']) to ensure listeners are fired off synchronously. (Make sure to change it back in a subsequent line after you trigger the listener that's intended to be synchronous, or else this could have unintended consequences for the rest of your App.) Then change your Listener so that whatever handle() does get stored in a property accessible by a new Getter method therein. This options is not advisable though. It can be done, but is so sloppy I hesitate to even suggest it. But I'm no stranger to making my code do weird things for the sake of unit-tests, so I'm not going to presume to know your circumstances.