My short answer is neither. They’re not functionally different and they both achieve the same goal in very similar ways.
There really is no functional difference between these two. The task library provides a simpler way to create and schedule new threads, and one is not better than the other. It entirely depends on your use case.
The coroutine library simply provides a way to create and control threads.
These two pieces of code behave identically:
task.spawn(function()
task.wait(2)
print("delayed")
end)
-- is identical to
coroutine.resume(coroutine.create(function()
task.wait(2)
print("delayed")
end))
Meanwhile, task.delay
is not spawning the thread immediately at all. Instead, the thread is spawned after the delay period (which, is definitely a lot different).
This might matter if you want to run code before you start your delay but in a new thread, such as if you want to keep track of this thread and then later task.cancel
it:
local childThread
task.spawn(function() -- Spawn this function in a new thread immediately (just like the coroutine.resume + coroutine.create combo)
childThread = coroutine.running() -- Grab the running thread
task.wait(2) -- wait 2 seconds (now the code after task.spawn will run)
print("delayed")
end)
-- Cancel the thread immediately (now it won't run)
-- If you comment this out, you'll see "ran", then "delayed" after 2 seconds
task.cancel(childThread)
print("ran")
Another way to write this (with coroutine
would be like so):
-- Create the child thread
local childThread = coroutine.create(function()
task.wait(2) -- wait 2 seconds (now the code after task.spawn will run)
print("delayed")
end)
-- Start the child thread immediately
coroutine.resume(childThread)
-- Cancel the thread immediately (now it won't run)
-- If you comment this out, you'll see "ran", then "delayed" after 2 seconds
coroutine.close(childThread)
print("ran")
You can even combine the two libraries if you felt like it:
local thread = coroutine.create(callback)
-- Defer starting the thread
task.defer(thread)
P.s. @Valkyrop the replies in the post you linked are unfortunately misinformative imo. You can start/stop task.spawn
ed threads, you can really do that with any thread, it’s just a feature of lua threads.
coroutine
is nothing more than a library to work with lua threads in lua. Meanwhile, despite being very similar, the task
library acts as a versatile way to schedule threads. Both ultimately are two ways to interact with threads, and coroutine
and task
both see their own unique uses that the other doesn’t naturally support (except technically task.spawn
but imo task.spawn(callback)
is a lot nicer to write than coroutine.resume(coroutine.create(callback))
).
If you couldn’t start/stop a thread created by task.spawn
like you can in coroutines, you couldn’t call task.wait
in it, because internally, all task.wait
is doing is yielding and then resuming the thread you call it in after the time you specify has elapsed.