Stop a function when an event is fired using promises?

I’m trying to stop a function when an event is fired, like so:

function thing()
       game.Players.PlayerRemoving:connect(function(p)
               -- some condition goes here
               if (p.Name == "player") then
                       -- stop `thing` here ... not sure how
                       -- but the "return" keyword doesn't work here obviously
               end
       end)

       -- yielding code
end

I read another post here suggesting to use promises if you want to achieve this, but I’m quite new to using promises and I don’t understand what to do exactly (even after reading the api)

Say,

function thing()
       local promise
       promise = Promise.new(function(resolve, reject, onCancel)
               onCancel(function()
                       -- some cleanup for the game goes here
               end)
               -- yielding code, say
               for i = 1,30 do
                       task.wait(1)
                       print("i: #"..i)
               end
       end)
       game.Players.PlayerRemoving:connect(function(p)
               -- some condition goes here
               if (p.Name == "player") then
                       promise:cancel()
               end
       end)
end

But the yielding code still runs despite the cancellation of the promise. I can’t think of how to fix this.

You don’t need promises for this. Just check the condition and cancel execution.

local condition = true

function stuff()
   stuff1()
   if not condition then return end
   stuff2()
end

function cancel()
   condition = false
end
1 Like

I don’t think this is a viable solution considering that I would have to attach

if not condition then return end

on every line for thing() …

I want the function to end the instant the event is fired

Well that’s not really possible anyway. Lua is single-threaded. You can’t run two functions at the exact same time. The only way function B can change a value during execution of function A is if function A yields (which allows function B to execute). You only need to check the condition after you pick up from a yield.

I want to bring up this post again because it is delaying my work and I’m still at a loss for what to do. I’m sure there is an alternative way to do it – with or without promises – as seen in other games when the round ends almost immediately when a particular player leaves (like the murderer in Murder Mystery 2).

To use promise check out the API https://eryn.io/roblox-lua-promise/lib/#new. Here are some pointers.

First you need promise.race as this is a race condition, you don’t know which will happen first either all players leave or round is over you just want to end it once the race is over.

  local promises = {
    returnsAPromise("example 1"),
    returnsAPromise("example 2"),
    returnsAPromise("example 3"),
  }

  return Promise.race(promises) -- Only returns 1st value to resolve or reject

One promise will be a a promise from event which is player leaving, here you can detect the amount of players in a match and return true or false,.

Edit: actually you will need to create a custom event with a bindable event or signal as it resolves when the event is fired. The event fire when all players have left the match.

-- Creates a Promise which only resolves when `somePart` is touched by a part named `"Something specific"`.
return Promise.fromEvent(somePart.Touched, function(part)
  return part.Name == "Something specific"
end)

The other promise will be the waiting promise which resolves once the round is over:

local myFunction()
  return Promise.new(function(resolve, reject, onCancel)
    wait(1)
    resolve("Hello world!")
  end)
end

myFunction():andThen(print)

Then after the promise race resolves you can immediately switch to another promise which is the intermission loop, Check this out which is what led me to check out promises.

I suggest making your own game loop using print statements and see how it goes.

2 Likes