피드로 돌아가기
Async Transactions for Signals: Batching Updates Across await
Dev.toDev.to
Frontend

await 경계 간 상태 업데이트를 단일 Effect로 통합하는 Async Transaction 설계

Async Transactions for Signals: Batching Updates Across await

Luciano03222026년 4월 27일10advanced

Context

기존 Signal 시스템은 동일 Call Stack 내 업데이트는 Batching이 가능하나, await 발생 시 새로운 Microtask가 생성되어 Effect가 중복 실행되는 한계 존재. 비동기 작업 사이의 여러 상태 변경이 각각 독립적인 Flush를 유발하여 불필요한 리렌더링 및 중간 상태 노출 문제 발생.

Technical Solution

  • 기존 batchDepth 카운터를 재활용하여 batch()transaction()의 중첩 호출이 가능한 계층 구조 설계
  • batchDepth > 0 상태에서 scheduleJob() 호출 시 Microtask 예약 없이 Queue에 Job만 적재하는 지연 실행 메커니즘 적용
  • isPromiseLike 검사를 통해 비동기 함수 완료 시점까지 batchDepth 감소와 flushJobs() 호출을 유예하는 Promise 체이닝 구현
  • try...catch...finally 블록을 통한 예외 상황에서도 batchDepth를 정상 복구하여 스케줄러 교착 상태를 방지하는 안정성 확보
  • computed 노드는 상태 변경 시 Stale 마킹만 수행하고 실제 계산은 Flush 시점으로 미루는 Lazy Evaluation 유지

- 비동기 API 호출 전후로 여러 상태를 변경해야 하는 경우 Async Transaction 도입 검토 - UI 프레임워크의 Transition/Animation과 데이터 커밋 타이밍을 분리하여 설계 - 전역 상태 업데이트 전 로컬 Signal/State에서 Draft 패턴을 적용해 최종 결과만 커밋하는 구조 지향

원문 읽기