Antipattern: استخدام قيمة وظيفة الانتظار (()) في رمز JavaScript

أنت تعرض مستندات Apigee Edge.
انتقل إلى مستندات Apigee X.
معلومات

تسمح لك سياسة JavaScript في Apigee Edge بإضافة رمز مخصّص يتم تنفيذه في سياق مسار الخادم الوكيل لواجهة برمجة التطبيقات. على سبيل المثال، يمكن استخدام الرمز المخصّص في سياسة JavaScript لتنفيذ ما يلي:

  • الحصول على متغيّرات المسار وضبطها
  • تنفيذ المنطق المخصّص ومعالجة الأخطاء
  • استخراج البيانات من الطلبات أو الردود
  • التعديل الديناميكي لعنوان URL المستهدف في الخلفية
  • إضافة رؤوس أو إزالتها ديناميكيًا من طلب أو استجابة
  • تحليل استجابة JSON

عميل HTTP

يُعدّ عميل HTTP من الميزات الفعّالة لسياسة JavaScript. يمكن استخدام مزوّد خدمة HTTP (أو عنصر httpClient) لإجراء مكالمة واحدة أو متعددة إلى الخلفية أو الخدمات الخارجية. يكون برنامج HTTP مفيدًا بشكل خاص عند الحاجة إلى إجراء مكالمات إلى خدمات خارجية متعددة وتجميع الردود في واجهة برمجة تطبيقات واحدة.

نموذج رمز JavaScript يوجّه طلبًا إلى الواجهة الخلفية باستخدام كائن httpClient

var headers = {'X-SOME-HEADER' : 'some value' };
var myRequest = new Request("http://www.example.com","GET",headers);
var exchange = httpClient.send(myRequest);

يعرض الكائن httpClient الطريقتين get وsend (يتم استخدام send في نموذج الرمز أعلاه) لإرسال طلبات HTTP. كلتا الطريقتين غير متزامنتين، ويتم عرض عنصر exchange قبل اكتمال طلب HTTP الفعلي.

قد تستغرق طلبات HTTP بضع ثوانٍ إلى بضع دقائق. بعد تقديم طلب HTTP، من المهم معرفة وقت اكتماله حتى تتم معالجة الردّ من الطلب. إحدى الطرق الأكثر شيوعًا لتحديد وقت اكتمال طلب HTTP هي استدعاء طريقة waitForComplete() لكائن exchange.

waitForComplete()

تؤدي الطريقة waitForComplete() إلى إيقاف سلسلة المحادثات مؤقتًا إلى أن يكتمل طلب HTTP ويتم عرض الاستجابة (نجح/تعذّر الإجراء). بعد ذلك، يمكن معالجة الاستجابة الواردة من الخلفية أو الخدمة الخارجية.

نموذج رمز JavaScript باستخدام الدالة longForComplete()

var headers = {'X-SOME-HEADER' : 'some value' };
var myRequest = new Request("http://www.example.com","GET",headers);
var exchange = httpClient.send(myRequest);
// Wait for the asynchronous GET request to finish
exchange.waitForComplete();

// Get and Process the response
if (exchange.isSuccess()) {
    var responseObj = exchange.getResponse().content.asJSON;
    return responseObj.access_token;
} else if (exchange.isError()) {
    throw new Error(exchange.getError());
}

نقوش

سيؤدّي استخدام waitForComplete() بعد إرسال طلب HTTP في رمز JavaScript إلى تأثيرات على الأداء.

يمكنك استخدام رمز JavaScript التالي الذي يستدعي waitForComplete() بعد إرسال طلب HTTP.

رمز sample.js

// Send the HTTP request
var exchangeObj = httpClient.get("http://example.com");
// Wait until the request is completed
exchangeObj.waitForComplete();
// Check if the request was successful
if (exchangeObj.isSuccess())  {

    response = exchangeObj.getResponse();
    context.setVariable('example.status', response1.status);
} else {
   error = exchangeObj.getError();
   context.setVariable('example.error', 'Woops: ' + error);
}

في هذا المثال:

  1. يرسل رمز JavaScript طلب HTTP إلى واجهة برمجة تطبيقات الخلفية.
  2. وتطلب بعد ذلك waitForComplete() لإيقاف التنفيذ مؤقتًا حتى يكتمل الطلب.

    تؤدي waitForComplete() API إلى حظر سلسلة المهام التي تنفّذ رمز JavaScript إلى أن تنتهي معالجة الطلب في الخلفية وتردّ عليه.

هناك حد أقصى لعدد سلاسل المحادثات (%30) التي يمكنها تنفيذ رمز JavaScript بالتزامن على معالج الرسائل في أي وقت. وبعد بلوغ هذا الحدّ، لن تتوفّر أي سلاسل محادثات لتنفيذ رمز JavaScript. وبالتالي، إذا كان هناك عدد كبير جدًا من الطلبات المتزامنة التي تنفِّذ واجهة برمجة التطبيقات waitForComplete() في رمز JavaScript، ستتعذّر الطلبات اللاحقة مع ظهور رسالة الخطأ 500 خطأ في الخادم الداخلي ورسالة الخطأ "انتهت مهلة الانتظار" حتى قبل انتهاء مهلة سياسة JavaScript.

بشكل عام، قد يحدث هذا السيناريو إذا استغرقت الخلفية وقتًا طويلاً لمعالجة الطلبات أو إذا كان هناك عدد كبير من الزيارات.

التأثير

  1. لن تنجح طلبات البيانات من واجهة برمجة التطبيقات مع ظهور خطأ في الخادم الداخلي 500 و مع ظهور رسالة الخطأ "انتهت المهلة". عندما يتجاوز عدد الطلبات المتزامنة التي يتم تنفيذها waitForComplete() في رمز JavaScript الحد الأقصى المحدّد مسبقًا.
  2. قد يكون تشخيص سبب المشكلة أمرًا صعبًا نظرًا لتعذُّر تشغيل JavaScript مع ظهور الرسالة "انتهت المهلة". على الرغم من عدم انقضاء المهلة الزمنية المحددة لسياسة JavaScript المحدّدة.

أفضل الممارسات

يمكنك استخدام عمليات الاستدعاء في برنامج HTTP لتبسيط رمز وسيلة الشرح وتحسين الأداء وتجنُّب استخدام waitForComplete() في رمز JavaScript. وتضمن هذه الطريقة عدم حظر سلسلة التعليمات التي تنفّذ JavaScript إلى أن يكتمل طلب HTTP.

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

نموذج رمز JavaScript باستخدام عمليات معاودة الاتصال في httpClient

function onComplete(response,error) {
 // Check if the HTTP request was successful
    if (response) {
      context.setVariable('example.status', response.status);
     } else {
      context.setVariable('example.error', 'Woops: ' + error);
     }
}
// Specify the callback Function as an argument
httpClient.get("http://example.com", onComplete);

محتوى إضافي للقراءة