Flutter / دليل حلول تحريري
منع النتائج المتقادمة بعد البحث أو الخروج
أعد إنتاج الاكتمال غير المرتب واحم حداثة الطلب وملكية الجلسة معا.
قاعدة معرفة للقراءة فقط · بلا تعليقات عامة
تعرّف على الأعراض
يظهر البحث B صحيحا ثم يستبدله رد أبطأ للبحث A. وفي حالة أخرى يملأ طلب الحساب السابق الشاشة بعد الخروج والدخول.
يوجد فحص mounted بالفعل، لذلك لا يحدث خطأ setState بعد التحرير رغم انتماء البيانات المعروضة إلى مدخلات متقادمة.
افهم الأسباب المحتملة
- يتحقق mounted من عمر المالك لا من الاستعلام أو الجلسة صاحبة النتيجة. لا يمنح الاكتمال الناجح إذنا تلقائيا بالاعتماد.
- قد يُحمى فرع النجاح وحده، فيستبدل فشل قديم نجاحا أحدث. وقد يخلط مخزن مستودع عام بيانات نطاقات حسابات مختلفة.
سجّل هوية المدخل والمالك بأمان
استخدم تذاكر طلب مصطنعة وتسميات استعلام عامة وأجيال جلسات لإعادة بناء الترتيب. تجنب تسجيل الاستعلامات الشخصية كاملة أو الأسرار أو الردود. ميّز بدء الطلب من اكتماله ومن اعتماد الواجهة. إذا بدأ A قبل B واكتمل بعده فهذا سلوك غير متزامن طبيعي؛ الخلل في سياسة تسمح باعتماد A بعد تقادمه. افحص أيضا بقاء State نفسها عبر تغير المسار أو الحساب، فقد يجعل استمرارها فحص العمر وحده يبدو ناجحا.
أعلن سياسة الأوامر المقصودة
في البحث أثناء الكتابة يملك أحدث مدخل النتيجة المرئية غالبا. أما الحفظ المعاملي فقد لا يناسبه استبدال عملية قديمة لأنها ربما غيرت حالة بعيدة. اختر الاستبدال أو الرفض أو الطابور أو التسوية بحسب المهمة. يقلل تأخير الاستجابة للكتابة عدد البدايات لكنه لا يضمن ترتيب عمليات بدأت فعلا. وقد يوفر الإلغاء الموارد حيث يُدعم، لكن رد نداء متأخر أو اكتمالا غير مؤكد ما زال يحتاج إلى قاعدة ملكية. افصل هذه الآليات في التنفيذ والاختبار.
افحص الجيلين قبل الاعتماد
التقط جيل الجلسة الحالي وتذكرة طلب جديدة عند البدء. وعند الاكتمال قارن كليهما بالقيم الحالية إلى جانب عمر State. وتوضع الفحوص نفسها في فرع الخطأ. يعرض المقتطف البوابة فقط عمدا؛ ويملك النموذج المحيط الانتقالات والإبطال. زِد جيل الجلسة عند تغير ملكية الحساب وحدّد نطاق المخازن وفقا لذلك. لا تكتف بإخفاء الشاشة القديمة بينما تستطيع حالتها المشتركة إشعار واجهة مستخدم جديد.
final requestTicket = ++requestGeneration;
final sessionTicket = sessionGeneration;
final next = await repository.search(query);
if (!mounted || requestTicket != requestGeneration ||
sessionTicket != sessionGeneration) return;
setState(() { results = next; });
// Apply the same identity gate before committing an error.
Only a completion matching the current request and session may commit.
هذا مقتطف State وليس إلغاء ولا آلية تفويض خادم. لم يُنفذ أي طلب هنا.
ابن إعادة إنتاج محددة النتائج
وفّر مستودعا مزيفا بردود معلقة يتحكم بكل منها منفصلا. ابدأ A ثم B وأكمل B بنجاح ثم A أخيرا وأكّد بقاء B حالية. كرر بفشل A وبالتحرير قبل الاكتمال وبالخروج ثم جلسة جديدة قبل حل A. لا تتطلب الحالات خدمة حية أو نوما عشوائيا. وإذا خزّن النموذج النتائج، فأكّد تضمين نطاق الحساب الصحيح في المفتاح ومنع نشر البيانات الخاصة القديمة عبر مستمع آخر بعد رفض بوابة الواجهة لها.
تحقق من نجاح الإصلاح
يبقى النجاح الأحدث بعد نجاح أقدم أو فشله، ولا يتلقى المالك المحرر اعتمادات، ويبطل تبديل الحساب نتائج الجلسة السابقة ونشر مخزنها.
أبلغ عنها كاختبارات سياسة تطبيق عند استعمال البدائل. يحتاج الإلغاء الأصلي وإنهاء النقل والتفويض في الخادم إلى أدلة تكامل مستقلة.
امنع تكرار المشكلة
- أبق العمر والحداثة والإلغاء والتفويض عقودا مستقلة صريحة. أعد استخدام عينة ردود مؤجلة صغيرة وألزم مسارات النجاح والخطأ غير المتزامنة بسياسة الملكية نفسها.