call<T> method

void call<T>({
  1. required K key,
  2. required Future<T> task(),
  3. required void onSuccess(
    1. T data
    ),
  4. void onError(
    1. Object error
    )?,
})

Implementation

void call<T>({
  required K key,
  required Future<T> Function() task,
  required void Function(T data) onSuccess,
  void Function(Object error)? onError,
}) {
  // ลบ async ออกจากหัวฟังก์ชันนี้ เพื่อคุมลำดับเอง

  // 1. จัดการงานเก่า
  final old = _registry[key];
  if (old != null && !old.isCompleted) {
    old.completeError('_superseded_');
  }

  final completer = Completer<T>();
  _registry[key] = completer;

  // 2. ผูก Error Listener ไว้กับ Future ทันที (ป้องกัน Error หลุดไป Global)
  completer.future
      .then((result) {
        if (_registry[key] == completer) {
          _registry.remove(key);
          onSuccess(result);
        }
      })
      .catchError((e) {
        if (e.toString() == '_superseded_' || e.toString() == '_disposed_') {
          return; // จบเงียบๆ ตามแผน
        }

        if (_registry[key] == completer) {
          _registry.remove(key);
          if (onError != null) {
            onError(e);
          } else {
            // แทนที่จะ rethrow เราใช้การพิมพ์บอก Developer
            print('Latest Task Error ($key): $e');
          }
        }
      });

  // 3. เริ่มรัน Task จริง
  // ใช้ปีกกาครอบเพื่อให้แน่ใจว่า task() จะไม่หลุดออกไปข้างนอก
  () async {
    try {
      final value = await task();
      if (!completer.isCompleted) completer.complete(value);
    } catch (e, stack) {
      if (!completer.isCompleted) completer.completeError(e, stack);
    }
  }();
}