Help with RunService

I want to store RunService loops so I can disconnect them when the projectile touches something.

local connections = {} <----------------- help
local nt = 0

RunService.Heartbeat:Connect(function()
	if projectile.PrimaryPart ~= nil then
		projectile:PivotTo(CFrame.new(0.5*g*nt*nt + v0*nt + x0, projectile.PrimaryPart.AssemblyLinearVelocity + projectile.PrimaryPart.Position))
	end
	nt = nt + RunService.Heartbeat:Wait()
			
	local results = GetTouchingParts(projectile.PrimaryPart)
	if results then
		hitDetection(results, projectile) <------------------- disconnect the loop on touch
	end
end)
local connections = {} <----------------- help
local nt = 0

local conn = RunService.Heartbeat:Connect(function()
	if projectile.PrimaryPart ~= nil then
		projectile:PivotTo(CFrame.new(0.5*g*nt*nt + v0*nt + x0, projectile.PrimaryPart.AssemblyLinearVelocity + projectile.PrimaryPart.Position))
	end
	nt = nt + RunService.Heartbeat:Wait()
			
	local results = GetTouchingParts(projectile.PrimaryPart)
	if results then
		hitDetection(results, projectile) <------------------- disconnect the loop on touch
	end
end)
table.insert(connections,conn) -- Here you're storing the connection

-- Just in case that you want to desconnect and remove that connection i will give you
-- a example here:
for i,connection in pairs(connections) do -- for loop to iterate all the connections 
connection:Disconnect() -- Disconnect the prev connection
table.remove(connections,i) -- Remove the connection from table
end

Also you can put that for loop after the if statment of the results

Where would I put this part of the code?

for i, connection in pairs(connections) do
	connection:Disconnect()
	table.remove(connections, i)
end

Code:

local connections = {}

local function isFiltered(filterDescendantsInstances, instanceToCheck)
	for _, filterInstance in ipairs(filterDescendantsInstances) do
		if filterInstance == instanceToCheck or filterInstance:IsAncestorOf(instanceToCheck) then
			return true
		end
	end
	return false
end

local function destroyProjectile(projectile)
	if projectile ~= nil then
		projectile:Destroy()
	end
end

local function hitDetection(hit, projectile)
	if hit ~= nil then
		local filteredCheck = isFiltered(castParams.FilterDescendantsInstances, hit)

		if not filteredCheck then
			local model = hit:FindFirstAncestorWhichIsA("Model")
			if model then
				local humanoid = model:FindFirstChild("Enemy")
				if humanoid and humanoid ~= nil and humanoid.Health > 0 then
					local damage = getAbility("Damage")
					if damage then
						humanoid:TakeDamage(damage)
					end

					if humanoid.Health <= 0 then
						getLoot(model.Name)
					end
				end
			end
			destroyProjectile(projectile)
		end
	end
end

local function GetTouchingParts(part)
	if part ~= nil then
		local connection = part.Touched:Connect(function() end)
		local results = part:GetTouchingParts()
		for i,v in pairs(results) do
			connection:Disconnect()
			return v
		end
	end
end

RemotesFolder.FireProjectile.Event:Connect(function(firePoint, hitPosition)
	castParams.FilterDescendantsInstances = {character, HeroAbilitiesFolder}

	local g = Vector3.new(0,-ToolData.EffectGravity,0)
	local x0 = firePoint.WorldPosition
	local t = ToolData.ProjectileTime

	local v0 = (hitPosition - x0 - 0.5*g*t*t)/t

	local projectile = ToolData.Projectile:Clone()
	projectile.Parent = HeroAbilitiesFolder

	local nt = 0
	
	local connection = RunService.Heartbeat:Connect(function()
		if projectile.PrimaryPart ~= nil then
			projectile:PivotTo(CFrame.new(0.5*g*nt*nt + v0*nt + x0, projectile.PrimaryPart.AssemblyLinearVelocity + projectile.PrimaryPart.Position))
		end
		nt = nt + RunService.Heartbeat:Wait()

		local results = GetTouchingParts(projectile.PrimaryPart)
		if results then
			hitDetection(results, projectile)
		end
	end)
	
	table.insert(connections, connection)
	
	Derbis:AddItem(projectile, ToolData.ProjectileDuration)
end)

you would add that piece of code in the part where the conections are supposed to be disconnected