[javascript] أين يجب أن يتم طلب ajax في تطبيق Flux؟


2 Answers

لدى Fluxxor مثال على التواصل غير المتزامن مع API.

تتحدث هذه المدونة عن هذا الموضوع وقد ظهرت في مدونة React.

أجد هذا سؤالًا مهمًا وصعبًا للغاية لم يتم الإجابة عليه بوضوح حتى الآن ، حيث لا يزال تزامن برامج الواجهة الأمامية مع الواجهة الخلفية بمثابة ألم.

هل يجب إجراء طلبات واجهة برمجة التطبيقات في مكونات JSX؟ المخازن؟ مكان آخر؟

أداء الطلبات في المتاجر يعني أنه إذا احتاج متجرين إلى نفس البيانات لإجراء معين ، فسيصدران متطلبين متشابهين (إلا إذا قمت بتقديم التبعيات بين المتاجر ، والتي لا أحبها حقًا )

في حالتي ، لقد وجدت هذا مفيدًا جدًا لوضع وعود Q كحملة من الإجراءات بسبب:

  • لا تحتاج إجراءاتي إلى أن تكون قابلة للتسلسل (لا احتفظ بسجل الأحداث ، ولا أحتاج إلى ميزة إعادة تشغيل الحدث في مصادر الأحداث)
  • إنه يزيل الحاجة إلى اتخاذ إجراءات / أحداث مختلفة (الطلب المطلق / الطلب مكتمل / فشل الطلب) ويجب أن يضاهيها باستخدام معرفات الارتباط عندما يمكن إطلاق الطلبات المتزامنة.
  • يسمح لـ مخزن متعددة للاستماع إلى إكمال نفس الطلب ، دون إدخال أي تبعية بين المخازن (ومع ذلك قد يكون من الأفضل إدخال طبقة التخزين المؤقت؟)

اجاكس هو الشر

أعتقد أن أياكس سوف يستخدم أقل وأقل في المستقبل القريب لأنه من الصعب جدا التفكير فيه. الطريق الصحيح؟ بالنظر إلى الأجهزة كجزء من النظام الموزع ، لا أعرف من أين صادفت هذه الفكرة لأول مرة (ربما في هذا الفيديو الملهم كريس غرانغر ).

فكر في الأمر. الآن من أجل قابلية التطوير ، نستخدم أنظمة موزعة مع الاتساق النهائي كمحركات تخزين (لأننا لا نستطيع التغلب على نظرية CAP ونريد أن نكون متوفرين). لا تتم مزامنة هذه الأنظمة من خلال الاقتراع على بعضها البعض (باستثناء ربما لعمليات توافق الآراء) ، بل تستخدم هياكل مثل CRDT وسجلات الأحداث لجعل جميع أعضاء النظام الموزع متناسقًا في النهاية (سيجتمع الأعضاء إلى نفس البيانات ، مع منح الوقت الكافي) .

الآن فكر في ما هو جهاز محمول أو متصفح. إنه مجرد عضو في النظام الموزع الذي قد يعاني من تأخر الشبكة وتقسيم الشبكة. (أي أنك تستخدم هاتفك الذكي في مترو الأنفاق)

إذا تمكنا من إنشاء قواعد بيانات للشبكات وقسم شبكة متسامحة (أعني أنه ما زال بإمكاننا إجراء عمليات الكتابة إلى عقدة معزولة) ، فيمكننا على الأرجح بناء برامج أمامية (متحركة أو سطح مكتب) مستوحاة من هذه المفاهيم ، تعمل بشكل جيد مع وضع عدم الاتصال المدعوم في المربع دون ميزات عدم توفر التطبيق.

أعتقد أننا يجب أن نلهم أنفسنا بالفعل كيف تعمل قواعد البيانات على تصميم تطبيقات الواجهة. شيء واحد يجب أن نلاحظه هو أن هذه التطبيقات لا تنفذ طلبات POST و PUT و GET ajax لإرسال البيانات إلى بعضها البعض ، بل تستخدم سجلات الأحداث و CRDT لضمان الاتساق في النهاية.

فلماذا لا نفعل ذلك على الواجهة؟ لاحظ أن الواجهة الخلفية تتحرك بالفعل في هذا الاتجاه ، باستخدام أدوات مثل كافكا التي تم تبنيها بشكل كبير من قبل اللاعبين الكبار. يرتبط هذا بطريقة ما بـ Event Sourcing / CQRS / DDD أيضًا.

تحقق من هذه المقالات الرائعة من مؤلفي كافكا لإقناع نفسك:

ربما يمكننا البدء عن طريق إرسال الأوامر إلى الخادم ، وتلقي مجموعة من أحداث الخادم (من خلال websockets for exemple) ، بدلاً من إطلاق طلبات Ajax.

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

ومع ذلك ، لا يزال من الصعب تصميم شيء من هذا القبيل لبعض الأسباب الواضحة:

  • يمتلك عميل الجوال / المتصفح الخاص بك موارد محدودة ولا يمكنه بالضرورة تخزين كافة البيانات محليًا (وبالتالي يتطلب أحيانًا الاقتراع مع محتوى ثقيل لطلب AJAX)
  • يجب أن لا يرى عميلك جميع بيانات النظام الموزع ، لذلك يتطلب بطريقة ما تصفية الأحداث التي يتلقاها لأسباب أمنية
Question

أنا أقوم بإنشاء تطبيق react.js مع بنية التدفق وأحاول معرفة أين ومتى يجب تقديم طلب البيانات من الخادم. هل هناك أي مثال على ذلك. (ليس تطبيق TODO!)




لقد تم استخدام مثال Binary موسى من المثال Fluxxor اياكس . هنا مثال بسيط للغاية باستخدام نفس النهج.

لدي متجر منتج بسيط بعض إجراءات المنتج ومكون عرض وحدة التحكم الذي يحتوي على مكونات فرعية تستجيب جميعها للتغييرات التي تم إجراؤها على متجر المنتج . على سبيل المثال ، عناصر المنتج ، قائمة المنتجات ومكونات البحث عن المنتج .

عميل منتج مزيف

في ما يلي العميل المزيّف الذي يمكنك استبداله باستدعاء منتجات نهائية فعلية.

var ProductClient = {

  load: function(success, failure) {
    setTimeout(function() {
      var ITEMS = require('../data/product-data.js');
      success(ITEMS);
    }, 1000);
  }    
};

module.exports = ProductClient;

متجر المنتجات

هنا هو متجر المنتجات ، ومن الواضح أن هذا هو متجر صغير للغاية.

var Fluxxor = require("fluxxor");

var store = Fluxxor.createStore({

  initialize: function(options) {

    this.productItems = [];

    this.bindActions(
      constants.LOAD_PRODUCTS_SUCCESS, this.onLoadSuccess,
      constants.LOAD_PRODUCTS_FAIL, this.onLoadFail
    );
  },

  onLoadSuccess: function(data) {    
    for(var i = 0; i < data.products.length; i++){
      this.productItems.push(data.products[i]);
    }    
    this.emit("change");
  },

  onLoadFail: function(error) {
    console.log(error);    
    this.emit("change");
  },    

  getState: function() {
    return {
      productItems: this.productItems
    };
  }
});

module.exports = store;

الآن إجراءات المنتج ، والتي تجعل طلب AJAX ونجاح إطلاق النار على المنتجات LOAD_PRODUCTS_SUCCESS العودة إلى المتجر.

إجراءات المنتج

var ProductClient = require("../fake-clients/product-client");

var actions = {

  loadProducts: function() {

    ProductClient.load(function(products) {
      this.dispatch(constants.LOAD_PRODUCTS_SUCCESS, {products: products});
    }.bind(this), function(error) {
      this.dispatch(constants.LOAD_PRODUCTS_FAIL, {error: error});
    }.bind(this));
  }    

};

module.exports = actions;

لذا ، فإن استدعاء هذا this.getFlux().actions.productActions.loadProducts() من أي مكون يستمع إلى هذا المتجر يقوم بتحميل المنتجات.

يمكنك تخيل وجود إجراءات مختلفة على الرغم من أنها تستجيب لتفاعلات المستخدم مثل addProduct(id) removeProduct(id) وما إلى ذلك ... تتبع نفس النمط.

نأمل أن هذا المثال يساعد قليلا ، كما وجدت هذا صعب قليلا لتنفيذ ، ولكن بالتأكيد ساعد في الحفاظ على متجري متزامنة 100 ٪.







Related