Skip to content

7. 실행 제어: 일시 정지하고 다시 시작하기

YaksokSessionpause, resume 이벤트를 사용하면 코드의 실행을 잠시 멈추거나 재개할 수 있습니다. executionDelay 기능과 함께 사용하기 좋습니다.

실행 일시 정지하기: pause()

session.pause() 메서드를 호출하면, 현재 실행 중인 '달빛 약속' 코드는 가장 가까운 실행 단위(보통 한 줄)를 마친 뒤 즉시 멈춥니다. 한 실행 단위는 블럭 내의 한 줄이거나, 연산 구문 내의 한 항입니다.

typescript
session.pause() // 코드 실행을 일시 정지합니다.

단계별 실행 활성화: session.stepByStep = true

session.stepByStep 속성을 true로 설정하면, 코드는 각 실행 단위(보통 한 줄)를 마칠 때마다 자동으로 일시 정지됩니다. 이는 디버깅 목적으로 각 코드 라인의 실행을 정밀하게 제어할 때 유용합니다. session.stepBySteptrue일 때는 session.pause()를 명시적으로 호출하지 않아도 resume()이 호출될 때까지 다음 실행으로 넘어가지 않습니다.

typescript
session.stepByStep = true // 단계별 실행 모드를 활성화합니다.

실행 재개하기: resume()

일시 정지된 세션은 session.resume() 메서드를 호출하여 다시 실행할 수 있습니다. resume() 메서드는 Promise<void>를 반환하며, 코드 실행이 완전히 종료되었을 때 resolve됩니다. 따라서 await session.resume() 구문을 사용하면 실행이 끝날 때까지 기다릴 수 있습니다.

typescript
await session.resume() // 코드 실행을 재개하고, 실행이 끝날 때까지 기다립니다.

runningCode, pauseresume 이벤트 구독하기

SessionConfigevents 객체를 통해 runningCode, pauseresume 이벤트를 구독할 수 있습니다. 이를 통해 세션이 멈추거나 다시 시작될 때 특정 동작(예: UI 업데이트)을 수행할 수 있습니다.

  • events.runningCode(range, end, scope, tokens): 한 실행 단위의 코드가 실행되기 직전에 호출됩니다. stepByStep 모드에서는 이 이벤트가 발생한 후 자동으로 일시 중지됩니다.
  • events.pause(): session.pause()가 호출되어 실행이 멈췄을 때 호출됩니다. stepByStep 모드에서는 각 단계가 끝날 때마다 자동으로 호출됩니다.
  • events.resume(): session.resume()이 호출되어 실행이 재개될 때 호출됩니다.

전체 예제: pause()resume()

아래 예제는 executionDelaypause(), resume()을 사용하여 1초에 한 줄씩 코드를 실행하다가, 2.5초 뒤에 실행을 멈추고, 다시 2초 뒤에 실행을 재개하는 전체 과정을 보여줍니다.

typescript
import { SessionConfig, YaksokSession } from "@dalbit-yaksok/core";

let output = "";

const session = new YaksokSession({
  stdout(message: string) {
    output += message;
    console.log(`[출력] ${message}`);
  },
  events: { 
    pause() { 
      console.log("[알림] 실행이 일시 정지되었습니다."); 
    }, 
    resume() { 
      console.log("[알림] 실행을 다시 시작합니다."); 
    }, 
  }, 
});

session.addModule(
  "main",
  `
"A" 보여주기
"B" 보여주기
"C" 보여주기
"D" 보여주기
`,
  {
    executionDelay: 1000, // 1초에 한 줄씩 실행
  },
);

// runModule은 Promise를 반환하지만, 여기서는 await하지 않고 실행을 시작시킵니다.
const runningPromise = session.runModule("main");

// 2.5초 후에 실행을 일시 정지합니다.
setTimeout(() => {
  console.log("[제어] pause() 호출");
  session.pause();
  // 2.5초 시점에는 "A"와 "B"가 출력되었을 것입니다.
  console.log("현재까지의 출력:", output); // "AB"
}, 2500);

// 4.5초 후에 실행을 재개합니다. (일시 정지 후 2초 뒤)
setTimeout(async () => {
  console.log("[제어] resume() 호출");
  await session.resume();
  // resume()이 반환하는 Promise가 끝나면 모든 실행이 완료된 것입니다.
  console.log("최종 출력:", output); // "ABCD"
}, 4500);

// 전체 실행이 끝날 때까지 기다립니다.
await runningPromise;
console.log("모든 실행이 종료되었습니다.");

/*
[출력] A
[출력] B
[제어] pause() 호출
[알림] 실행이 일시 정지되었습니다.
현재까지의 출력: AB
[제어] resume() 호출
[알림] 실행을 다시 시작합니다.
[출력] C
[출력] D
최종 출력: ABCD
모든 실행이 종료되었습니다.
*/

전체 예제: stepByStep

stepBySteptrue로 설정하면 resume()이 호출될 때마다 한 단계씩 코드를 실행합니다.

typescript
import { YaksokSession } from "@dalbit-yaksok/core";

async function runStepByStep() {
  let output = "";
  const session = new YaksokSession({
    stdout(message) {
      output += message;
    },
    events: {
      runningCode(range, end, scope, tokens) {
        console.log(`[실행] ${tokens[0].value} (다음 단계 대기중...)`);
      },
    },
  });

  session.stepByStep = true;

  session.addModule(
    "main",
    `
"A" 보여주기
"B" 보여주기
"C" 보여주기
        `,
  );

  console.log("코드 실행 시작 (stepByStep 모드)...");
  const runPromise = session.runModule("main");

  // 첫 번째 '보여주기' 전에 일시 중지됨 (runningCode 이벤트 발생 후)
  await new Promise((resolve) => setTimeout(resolve, 50));
  console.log('resume 호출하여 "A" 실행...');
  session.resume(); // "A" 실행

  await new Promise((resolve) => setTimeout(resolve, 50));
  console.log('resume 호출하여 "B" 실행...');
  session.resume(); // "B" 실행

  await new Promise((resolve) => setTimeout(resolve, 50));
  console.log('resume 호출하여 "C" 실행...');
  session.resume(); // "C" 실행

  await runPromise;
  console.log("코드 실행 완료. 최종 출력:", output);
}

runStepByStep();