# RunLater

## Use RunLater&#x20;

***

The **RunLater** function is used to control the execution order sequentially. Below is an example code snippet.

```lua
-- Print "Hello, World" after 2 seconds
Client.RunLater(function()
 print("Hello, World") 
end, 2)
```

As shown above, after **n** seconds, the anonymous function passed as the first parameter will be executed. By using this, you can easily control desired operations after a certain amount of time has passed.

### Time Interval Guarantee Issue

***

Because the **RunLater** function executes a function after a certain period of time has passed, it isn’t influenced by the game’s frame rate. Therefore, it does not guarantee an exact time interval. Consider the following example:

```lua
-- 1초마다 메시지 출력
local startTime = os.time()

local function printMessage()
    local currentTime = os.time()
    local elapsedTime = currentTime - startTime
    print("Elapsed time: " .. elapsedTime .. "second")
end

local function runLaterExample()
    Client.RunLater(function()
        printMessage()
        runLaterExample()
    end, 1)
end

runLaterExample()
```

In the example above, we use **RunLater** to repeatedly execute a function that prints the elapsed time every second. However, since **RunLater** does not guarantee an exact time interval, the actual elapsed time may be slightly longer than one second.

### Performance Issues

***

Because **RunLater** runs on the game’s main thread, executing long-running tasks can affect the game’s performance. If you need to perform time-consuming operations using **RunLater**, you may need to implement additional handling.

```lua
-- Execute a long-running task after 5 seconds
Client.RunLater(5, function()
    -- Long-running task
    for i = 1, 1000000000 do
        -- Perform the task
    end
end)
```

In the example above, we’ve scheduled a long-running task to be executed after 5 seconds. Because this task takes a very long time, it can negatively impact the game’s performance.

In the following example, we’ll look at a scenario where the long-running task is divided into multiple steps. Each step is performed over a short period of time, and then proceeds to the next step.

```lua
local totalIterations = 1000000000
local iterationsPerFrame = 1000000
local currentIteration = 0

local function performWork()
    for i = 1, iterationsPerFrame do
        -- Perform work
        currentIteration = currentIteration + 1
        if currentIteration >= totalIterations then
            -- Work complete
            print("Work complete.")
            return
        end
    end

    -- Continue work in the next frame
    Client.RunLater(performWork, 0)
end

-- Start work in the first frame
performWork()
```

{% hint style="info" %}
Lua scripts do not inherently provide multi-threading capabilities, you must use alternative methods to handle long-running tasks.
{% endhint %}

In the example above, the long-running task is divided into increments of one million operations at a time. Each frame processes one million operations, and if the task isn’t finished, it continues in the next frame.

### Validity Guarantee Issue

***

A **RunLater** that executes after **n** seconds cannot guarantee the validity of its actions following the wait. For example, the object you’re trying to access might have been destroyed by the time those **n** seconds have passed.

```lua
local text = Text()
Client.RunLater(function()
    text.text = "Hello, World"
end, 2)

text = nil
print(text.text)
```

In the example above, the script attempts to access the properties of a **Text** object after 2 seconds. However, if the **Text** object has been destroyed within those 2 seconds, an error may occur. Therefore, it’s advisable to perform a validity check before accessing the object inside **RunLater**.

```lua
local text = Text()
Client.RunLater(function()
    if text ~= nil then
        text.text = "Hello, World"
    end
end, 2)
```

As shown above, it’s a good idea to perform a validity check to guard against cases where the **RunLater** function executes after the object has been destroyed. By using this approach, you can ensure the validity even if the object is no longer available.
