调度代码在许多情况下是有用的,例如确保代码在特定操作或周期完成后执行,或在特定时间内延迟代码。您可以使用 task 库来优化 Roblox 的 任务调度器,以管理和调度代码。您还可以使用一个类似的库,称为 coroutine,来调度代码,该库具有一些附加功能。
常用方法
以下是用于调度代码的最常用 task 方法。您应该使用任务方法,而不是旧的调度方法,例如 wait(),以确保您的代码以最佳方式运行。
下表列出了相关的遗留全局方法及其首选的、更优化的替代方法:
| 遗留全局方法 | 任务方法 | 其他替代方法 |
|---|---|---|
| wait() | task.wait() | RunService.Heartbeat |
| wait(n) | `Library.task.wait() | task.wait(n)` |
| spawn(f) | `Library.task.defer() | task.defer(f)` |
| delay(n, f) | `Library.task.delay() | task.delay(n, f)` |
| spawn(function() f(uv1, ...) end) | `Library.task.defer() | task.defer(f, uv1, ...)` |
| delay(n, function() f(uv1, ...) end) | `Library.task.delay() | task.delay(n, f, uv1, ...)` |
task.spawn()
task.spawn() 接受一个线程或函数,并通过引擎的调度器 立即 恢复它。额外的参数被传递给正在恢复的线程或函数。
以下代码示例展示了如何在调用可能会在遍历一组对象时暂停的函数时使用 task.spawn()。
local function playerAdded(player)
print(player)
end
for _, player in Players:GetPlayers() do
task.spawn(playerAdded, player)
end
task.defer()
task.defer() 接受一个线程或函数,并将其延迟到当前帧的当前恢复点结束后。额外的参数被传递给正在恢复的线程或函数。
通常在您希望获得与 task.spawn() 类似的行为但不需要线程立即运行时使用。以下代码示例说明了 print() 语句对于 "A" 将在 "B" 的 print() 语句执行后延迟:
task.defer(print, "A")print("B")--> B--> A
task.delay()
task.delay() 接受一个线程或函数,并在给定的时间经过后调度它在下一个 Heartbeat 步骤中恢复。该线程恢复时具有内置的错误处理和对其他引擎功能的支持。任何额外的参数都传递给正在恢复的线程或函数。
由于实际延迟时间可能有所不同,以下代码示例说明了您如何通过将当前时间作为参数传递来计算它:
task.delay(2, function(scheduledTime)
print(os.clock() - scheduledTime) --> 2.038702
end, os.clock())
持续时间为零将导致线程或函数在下一个步骤中恢复。
task.wait()
task.wait() 会让当前线程暂停,直到给定的持续时间(以秒为单位)结束,然后在下一个 Heartbeat 步骤中恢复该线程。
实际的暂停时间可能会有所不同。以下代码示例说明了该方法方便地返回它:
由于实际的延迟时间可能会有所不同,以下代码示例说明了您如何通过存储该方法的返回值来获取实际时间:
local elapsedTime = task.wait(2) -- 等待 2 秒print(elapsedTime) --> 2.0792941
如果没有给定持续时间,持续时间将默认为零,这意味着线程会自动在下一个步骤中恢复。这意味着 task.wait() 的行为等同于 RunService.Heartbeat。