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

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

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

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

عميل HTTP

إحدى الميزات الفعّالة لسياسة JavaScript هي عميل HTTP. يمكن استخدام عميل 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، من المهم معرفة وقت اكتماله، بحيث يمكن معالجة الاستجابة من الطلب. تُعدّ استدعاء الإجراء waitForComplete() لكائن exchange إحدى الطرق الأكثر شيوعًا لتحديد وقت اكتمال طلب HTTP.

waitForComplete()

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

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

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() واجهة برمجة التطبيقات إلى حظر سلسلة التعليمات التي تنفّذ رمز JavaScript إلى أن تكتمل الخلفية من معالجة الطلب وتستجيب.

هناك حد أقصى لعدد سلاسل المحادثات (%30) التي يمكنها تنفيذ رمز JavaScript بشكل متزامن في معالج الرسائل في أي وقت. وبعد الوصول إلى هذا الحد، لن تكون هناك أي سلاسل محادثات متاحة لتنفيذ رمز JavaScript. وبالتالي، إذا كان هناك عدد كبير جدًا من الطلبات المتزامنة التي تنفّذ waitForComplete() API في رمز 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);

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