> For the complete documentation index, see [llms.txt](https://docs.decentraland.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.decentraland.org/creator/content-creator-ko/sdk7/programming-patterns/async-functions.md).

# 비동기 함수

씬 코드에서 언제, 어떻게 비동기 함수를 실행해야 하는지 알아봅니다.

## 개요

장면의 코드 대부분은 단일 스레드를 사용하여 동기적으로 실행됩니다. 즉, 명령은 한 줄씩 순차적으로 실행됩니다. 각 명령은 실행을 시작하기 전에 먼저 이전 명령의 실행이 끝나기를 기다려야 합니다.

장면의 시스템에 있는 함수들조차도 다음에 따라 하나씩 실행됩니다. [우선순위 순서](/creator/content-creator-ko/sdk7/architecture/systems.md#system-execution-order).

코드를 동기적으로 실행하면 일관성이 보장됩니다. 코드의 명령이 어떤 순서로 실행되는지 항상 확실히 알 수 있기 때문입니다.

반면, 장면은 다음 프레임을 구성하기 위해 초당 여러 번 업데이트되어야 합니다. 코드의 일부가 응답하는 데 너무 오래 걸리면 전체 메인 스레드가 멈추고, 그 결과 프레임 속도가 느려집니다.

그래서 어떤 경우에는 일부 명령을 비동기적으로 실행하고 싶습니다. 이는 작업을 시작해 두는 동안 장면이 다음 코드 줄들을 계속 실행할 수 있다는 뜻입니다. 장면은 여전히 모든 것을 단일 스레드에서 실행하지만, 비동기 작업이 응답을 기다리는 동안 나머지 코드는 차단되지 않습니다.

응답하는 데 시간이 걸릴 수 있는 외부 서비스에 의존하는 작업에 특히 유용합니다. 그 응답을 기다리는 유휴 시간이 다른 작업을 막지 않도록 하고 싶기 때문입니다.

예를 들면:

* REST API에서 데이터를 가져올 때
* 블록체인에서 트랜잭션을 수행할 때

{% hint style="warning" %}
**📔 참고**: 작업이 실행을 마치기 전에 장면의 여러 프레임이 렌더링될 수 있다는 점을 기억하세요. 비동기 작업이 완료되는 동안 중간 상황을 처리할 수 있을 만큼 장면의 코드가 유연한지 확인하세요.
{% endhint %}

## 비동기 함수를 실행하기

아무 함수나 다음으로 표시하세요 `비동기` 그래서 기다리는 동안 장면의 나머지 코드를 차단하지 않고 비동기적으로 실행되도록.

```ts
// 비동기 함수 선언
async function myAsyncTask() {
	// 함수의 단계 실행
}

// 비동기 함수 호출
myAsyncTask()

// 나머지 코드는 계속 실행됨
```

## executeTask 함수

이 `executeTask()` 함수는 람다 함수를 비동기적으로 실행합니다. `executeTask()` 함수를 선언하고 실행하는 것을 모두 하나의 동일한 문장에서 할 수 있게 해줍니다.

```ts
executeTask(async () => {
	let data = await myAsyncTask()
	console.log(data)
})

// 나머지 코드는 계속 실행됨
```

## then 함수

이 `then` 함수는 인수로 람다 함수를 받으며, 이 람다 함수는 이전 문장이 끝난 뒤에만 실행됩니다. 이 람다 함수는 선택적으로 이전 문장이 반환하는 값에 매핑된 입력을 가질 수 있습니다.

```ts
myAsyncTask().then((data) => {
	console.log(data)
})
```

{% hint style="warning" %}
**📔 참고**: 일반적으로 다음을 사용하는 것이 더 좋습니다. `executeTask` 접근 방식이 다음보다 `then` 함수. 다음에 너무 많이 의존하면 `then` 함수를 여러 중첩 수준에서 사용하게 되면, "콜백 지옥(callback hell)"이라 불리는 상황에 빠질 수 있으며, 이 경우 코드를 읽고 유지보수하기가 매우 어려워질 수 있습니다.
{% endhint %}

## PointerEvents 및 RayCast 함수

장면이 다음을 사용할 때 `PointerEvent` 나 `RayCast` 컴포넌트, 충돌 계산은 엔진에서 비동기적으로 수행됩니다. 그런 다음 엔진은 장면에 결과 이벤트를 반환하는데, 이 이벤트는 호출 시점보다 게임 루프의 한 틱 또는 여러 틱 뒤에 도착할 수 있습니다.

그다음에는 결과가 도착한 프레임에서 이를 처리할 시스템을 만들어야 합니다.

{% hint style="warning" %}
**📔 참고**: 클릭을 다음을 통해 처리하는 경우 [**콜백 등록**](/creator/content-creator-ko/sdk7/interactivity/button-events/register-callback.md) 방식을 사용하면 이를 처리하기 위한 시스템을 명시적으로 만들 필요는 없지만, 동일한 작업이 백그라운드에서 진행됩니다.
{% endhint %}

다음 [클릭 이벤트](/creator/content-creator-ko/sdk7/interactivity/button-events/click-events.md) 과 [레이캐스팅](/creator/content-creator-ko/sdk7/interactivity/raycasting.md).

{% hint style="info" %}
**💡 팁**: 레이캐스트 결과 처리에 많은 계산이 필요하다면(경로 탐색 알고리즘을 실행하는 것처럼) 그 계산을 비동기 함수에서 실행하고 싶을 수 있습니다.
{% endhint %}

## await 문

하나의 `await` 문은 다음 코드 줄로 넘어가기 전에 실행이 응답을 기다리도록 강제합니다. `await` 문은 비동기 코드 블록 안에서만 사용할 수 있습니다.

```ts
// 함수 선언
async function myAsyncTask() {
	try {
		let response = await fetch(callUrl)
		let json = await response.json()
		console.log(json)
	} catch {
		console.log('URL에 연결하지 못했습니다')
	}
}

// 함수 호출
myAsyncTask()

// 나머지 코드는 계속 실행됨
```

위 예제는 다음을 포함하는 함수를 실행합니다. `fetch()` 외부 API에서 데이터를 가져오는 작업입니다. 이 `fetch()` 작업은 비동기적입니다. 서버가 응답하는 데 얼마나 걸릴지 예측할 수 없기 때문입니다. 그러나 다음 줄은 이를 JSON으로 파싱하기 전에 이 작업의 출력이 준비되어 있어야 합니다. 여기서 `await` 문은 이 작업이 값을 반환한 뒤에만 다음 줄이 실행되도록 보장합니다. 마찬가지로 `response.json()` 함수 역시 비동기적이지만, 다음 줄은 로그를 남기기 전에 JSON이 파싱되어야 합니다. 두 번째 `await` 문은 JSON 파싱이 완료된 뒤에만 다음 줄이 호출되도록 강제하며, 시간이 얼마나 걸리든 상관없습니다.

## 함수 호출에 타임아웃 설정하기

다음을 사용하세요 `setTimeout` 특정 코드 줄이 실행되기 전에 잠시 기다리도록 합니다. 이는 두 개의 인수를 받습니다:

* 실행할 함수
* 그 함수를 실행하기 전에 기다릴 밀리초 수

아래 예제는 콘솔에 메시지를 기록하는 간단한 함수를 실행하기 전에 1000밀리초(1초)에 해당하는 시간을 기다립니다.

```ts
import { timers } from '@dcl/sdk/ecs'

console.log('이것은 바로 출력됩니다')

timers.setTimeout(() => {
	// 지연 후 실행할 함수
    console.log('이것은 1초 후에 출력됩니다')
}, 1000)
```

이 `clearTimeout` 를 사용하면 다음의 실행을 취소할 수 있습니다. `setTimeout` 아직 실행을 기다리고 있는 함수. `setTimeout` 타이머 ID(숫자)를 반환하며, 이를 다음에 전달할 수 있습니다 `clearTimeout` . 이 경우 변수 `timeoutId` 는 다음을 수행할 때 얻어집니다 `setTimeout` , 그리고 다음에 전달됩니다 `clearTimeout` 이를 취소하기 위해

```ts
import { timers } from '@dcl/sdk/ecs'

const timeoutId = timers.setTimeout(() => {
    console.log('이 함수를 실행하기까지 1초 기다리세요')
}, 1000)

timers.clearTimeout(timeoutId)
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.decentraland.org/creator/content-creator-ko/sdk7/programming-patterns/async-functions.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
