0Pricing
Java Academy · درس

معالجة الأخطاء وخط أنابيب HTTP غير المتزامن

عالج الأخطاء باستخدام exceptionally وhandle وwhenComplete، ثم أنشئ خط أنابيب عميل HTTP غير متزامن

معالجة الأخطاء وخط أنابيب HTTP غير المتزامن درس مجاني في Java Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Java Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Java Academy 4 دروس في المجموع.

أهمية معالجة الأخطاء غير المتزامنة

في المسارات غير المتزامنة، لا تنتشر الاستثناءات بالطريقة نفسها المتّبعة في الشيفرة المتزامنة. يجب أن تعالج الأخطاء صراحةً باستخدام exceptionally أو handle أو whenComplete.

exceptionally: التعافي من الأخطاء

يُستدعى exceptionally(Function<Throwable, T>) فقط عند اكتمال المستقبل بوقوع استثناء. ويوفّر قيمة بديلة، مما يُبقي مسار المعالجة مستمرًا.

CompletableFuture<String> safe = fetchUser(id)
    .thenApply(User::getName)
    .exceptionally(ex -> {
        log.warn("Fetch failed: " + ex.getMessage());
        return "Anonymous";
    });
System.out.println(safe.join()); // "Anonymous" if fetch failed

handle: تحويل النجاح والفشل

يُستدعى handle(BiFunction<T, Throwable, U>) عند النجاح والفشل معًا. ستكون إحدى الوسيطتين بقيمة null.

fetchUser(id).handle((user, ex) -> {
    if (ex != null) return UserDto.empty();
    return UserDto.from(user);
}).thenAccept(dto -> sendResponse(dto));

whenComplete: تأثير جانبي بعد أي نتيجة

يُستدعى whenComplete(BiConsumer) بعد الاكتمال بغضّ النظر عن النتيجة. ولا يغيّر النتيجة — استخدمه للتسجيل أو المقاييس أو التنظيف.

fetchUser(id)
    .whenComplete((user, ex) -> {
        if (ex != null) metrics.increment("user.fetch.error");
        else            metrics.increment("user.fetch.success");
    })
    .thenAccept(u -> sendResponse(u));

إعادة محاولة futures الفاشلة

نفّذ منطق إعادة المحاولة باستدعاء العملية بشكل递递?

CompletableFuture<String> withRetry(Supplier<CompletableFuture<String>> task, int retries) {
    return task.get().exceptionallyCompose(ex -> {
        if (retries > 0) {
            System.out.println("Retrying... " + retries);
            return withRetry(task, retries - 1);
        }
        return CompletableFuture.failedFuture(ex);
    });
}

Java 11 HttpClient: طلب GET غير متزامن

يوفّر HttpClient في Java 11 بروتوكول HTTP غير متزامن بالكامل عبر sendAsync()، مع إرجاع CompletableFuture<HttpResponse<String>>.

HttpClient client = HttpClient.newHttpClient();
HttpRequest req = HttpRequest.newBuilder()
    .uri(URI.create("https://api.example.com/users/1"))
    .build();
CompletableFuture<String> body = client
    .sendAsync(req, HttpResponse.BodyHandlers.ofString())
    .thenApply(HttpResponse::body);

تسلسل عدة طلبات HTTP

استخدم thenCompose لتسلسل طلبات HTTP التابعة: اجلب المستخدم أولًا، ثم استخدم معرّف المستخدم لجلب طلباته.

client.sendAsync(userReq, HttpResponse.BodyHandlers.ofString())
    .thenApply(r -> parseUser(r.body()))
    .thenCompose(user -> client.sendAsync(
        buildOrdersRequest(user.getId()),
        HttpResponse.BodyHandlers.ofString()))
    .thenApply(r -> parseOrders(r.body()))
    .thenAccept(orders -> System.out.println("Orders: " + orders.size()));

طلبات HTTP متوازية باستخدام allOf

أرسل الطلبات إلى عدة نقاط نهاية بالتوازي، ثم اجمع جميع الاستجابات عند اكتمالها جميعًا.

List<URI> endpoints = List.of(uri1, uri2, uri3);
List<CompletableFuture<String>> requests = endpoints.stream()
    .map(uri -> client.sendAsync(
            HttpRequest.newBuilder(uri).build(),
            HttpResponse.BodyHandlers.ofString())
        .thenApply(HttpResponse::body))
    .collect(Collectors.toList());
List<String> responses = CompletableFuture
    .allOf(requests.toArray(new CompletableFuture[0]))
    .thenApply(v -> requests.stream().map(CompletableFuture::join).collect(Collectors.toList()))
    .join();

مهلة زمنية لطلبات HTTP

طبّق orTimeout مباشرةً على طلب HTTP غير المتزامن لإلغائه إذا استغرق الخادم وقتًا أطول من اللازم.

CompletableFuture<String> result = client
    .sendAsync(req, HttpResponse.BodyHandlers.ofString())
    .orTimeout(5, TimeUnit.SECONDS)
    .thenApply(HttpResponse::body)
    .exceptionally(ex -> "timeout or error");

التحقق من رمز الحالة في مسار المعالجة

استخدم thenApply للتحقق من رمز حالة HTTP وإلقاء استثناء خاص بالنطاق إذا كان يشير إلى حدوث خطأ، مع الحفاظ على اتساق معالجة الأخطاء في مسار المعالجة.

.thenApply(response -> {
    if (response.statusCode() != 200)
        throw new HttpResponseException(response.statusCode());
    return response.body();
})

الجمع بين التعافي من الأخطاء والتسجيل

أضف whenComplete للتسجيل وexceptionally للتعافي في مسار المعالجة نفسه — إذ يعملان معًا بسلاسة.

fetchData()
    .whenComplete((r, ex) -> { if (ex != null) log.error("Failed", ex); })
    .exceptionally(ex -> fallback())
    .thenAccept(result -> process(result));

تحقق سريع

ما أسلوب CompletableFuture الذي يُستدعى فقط عند فشل المستقبل؟

مراجعة

استخدم exceptionally للقيم البديلة، وhandle لتحويل النتيجتين، وwhenComplete للتأثيرات الجانبية. ابنِ مسارات معالجة HTTP غير متزامنة باستخدام Java 11 HttpClient مع thenCompose وallOf.

الأسئلة الشائعة

هل درس «معالجة الأخطاء وخط أنابيب HTTP غير المتزامن» مجاني؟

نعم — نص درس «معالجة الأخطاء وخط أنابيب HTTP غير المتزامن» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Java Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Java Academy 4 دروس في المجموع.

ماذا ستتعلم في «معالجة الأخطاء وخط أنابيب HTTP غير المتزامن»؟

عالج الأخطاء باستخدام exceptionally وhandle وwhenComplete، ثم أنشئ خط أنابيب عميل HTTP غير متزامن تتمرن على Java Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Java Academy؟

لا تُشترط خبرة سابقة. Java Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.

كم من الوقت يستغرق درس «معالجة الأخطاء وخط أنابيب HTTP غير المتزامن»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Java Academy هذا؟

نعم. كل درس في Java Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. إنشاء CompletableFutures وإكمالها
  2. التسلسل باستخدام thenApply وthenCompose
  3. دمج Futures: ‏allOf وanyOf
  4. معالجة الأخطاء وخط أنابيب HTTP غير المتزامن
← العودة إلى Java Academy