আপনি যদি কখনও জাভাস্ক্রিপ্ট এপিআই ব্যবহার করে থাকেন একটি ফর্ম জমা বাড়াতে, তাহলে আপনি ভুলবশত একটি ডুপ্লিকেট-রিকোয়েস্ট/রেস-কন্ডিশন বাগ প্রবর্তন করেছেন। আজ, আমি আপনাকে সমস্যাটি এবং এটি এড়াতে আমার সুপারিশগুলি নিয়ে চলে যাব। fetch (আপনি যদি পছন্দ করেন তাহলে ভিডিও শেষে) এর একটি খুব মৌলিক বিবেচনা করা যাক একটি একক ইনপুট এবং একটি জমা বোতাম সহ। এইচটিএমএল ফর্ম <form method="post"> <label for="name">Name</label> <input id="name" name="name" /> <button>Submit</button> </form> যখন আমরা সাবমিট বাটনে চাপ দিব, ব্রাউজার পুরো পৃষ্ঠা রিফ্রেশ করবে। সাবমিট বোতামটি ক্লিক করার পরে ব্রাউজারটি কীভাবে পুনরায় লোড হয় তা লক্ষ্য করুন। পৃষ্ঠা রিফ্রেশ সবসময় আমরা আমাদের ব্যবহারকারীদের অফার করতে চাই না, তাই একটি সাধারণ বিকল্প ব্যবহার করা হয় ফর্মের "জমা দিন" ইভেন্টে একটি ইভেন্ট শ্রোতা যোগ করতে, ডিফল্ট আচরণ প্রতিরোধ করতে এবং API ব্যবহার করে ফর্ম ডেটা জমা দিতে। জাভাস্ক্রিপ্ট fetch একটি সরল পদ্ধতি নীচের উদাহরণ মত দেখতে হতে পারে. পৃষ্ঠা (বা উপাদান) মাউন্ট করার পরে, আমরা ফর্ম DOM নোড ধরি, একটি ইভেন্ট লিসেনার যোগ করি যা ফর্ম ব্যবহার করে একটি অনুরোধ তৈরি করে , , এবং , এবং হ্যান্ডলারের শেষে, আমরা ইভেন্টের পদ্ধতিকে কল করি। fetch কর্ম পদ্ধতি তথ্য preventDefault() const form = document.querySelector('form'); form.addEventListener('submit', handleSubmit); function handleSubmit(event) { const form = event.currentTarget; fetch(form.action, { method: form.method, body: new FormData(form) }); event.preventDefault(); } এখন, কোন জাভাস্ক্রিপ্ট হটশট GET বনাম পোস্ট সম্পর্কে আমাকে টুইট করা শুরু করার আগে এবং অনুরোধের বডি এবং আর যাই হোক না কেন, আমাকে শুধু বলতে দিন, আমি জানি। আমি অনুরোধটি ইচ্ছাকৃতভাবে সহজ রাখছি কারণ এটি মূল ফোকাস নয়। বিষয়বস্তুর প্রকার fetch এখানে মূল সমস্যা হল । এই পদ্ধতিটি ব্রাউজারকে নতুন পৃষ্ঠা লোড করার এবং ফর্ম জমা দেওয়ার ডিফল্ট আচরণ করতে বাধা দেয়। event.preventDefault() এখন, যদি আমরা স্ক্রিনের দিকে তাকাই এবং সাবমিট চাপি, আমরা দেখতে পাব যে পৃষ্ঠাটি পুনরায় লোড হচ্ছে না, তবে আমরা আমাদের নেটওয়ার্ক ট্যাবে HTTP অনুরোধটি দেখতে পাচ্ছি। লক্ষ্য করুন ব্রাউজারটি সম্পূর্ণ পৃষ্ঠা পুনরায় লোড করে না। দুর্ভাগ্যবশত, ডিফল্ট আচরণ প্রতিরোধ করতে JavaScript ব্যবহার করে, আমরা আসলে একটি বাগ প্রবর্তন করেছি যা ডিফল্ট ব্রাউজার আচরণে নেই। আমরা যখন প্লেইন ব্যবহার করি এবং আপনি সাবমিট বোতামটি সত্যিই দ্রুত গুচ্ছ গুচ্ছ করে ফেলবেন, আপনি লক্ষ্য করবেন যে সাম্প্রতিকতমটি ছাড়া সমস্ত নেটওয়ার্ক অনুরোধগুলি লাল হয়ে গেছে। এটি ইঙ্গিত দেয় যে সেগুলি বাতিল করা হয়েছে এবং শুধুমাত্র সাম্প্রতিক অনুরোধটিকে সম্মানিত করা হয়েছে৷ এইচটিএমএল যদি আমরা এটিকে জাভাস্ক্রিপ্ট উদাহরণের সাথে তুলনা করি, আমরা দেখতে পাব যে সমস্ত অনুরোধ পাঠানো হয়েছে, এবং তাদের সবগুলি বাতিল না করেই সম্পূর্ণ হয়েছে। এটি একটি সমস্যা হতে পারে কারণ যদিও প্রতিটি অনুরোধের জন্য আলাদা পরিমাণ সময় লাগতে পারে, তবে তারা শুরু করার চেয়ে ভিন্ন ক্রমে সমাধান করতে পারে। এর মানে হল যদি আমরা সেই অনুরোধগুলির রেজোলিউশনে কার্যকারিতা যোগ করি, তাহলে আমাদের কিছু অপ্রত্যাশিত আচরণ হতে পারে। একটি উদাহরণ হিসাবে, আমরা প্রতিটি অনুরোধের জন্য বৃদ্ধির জন্য একটি ভেরিয়েবল তৈরি করতে পারি (" ")। যতবার আমরা ফাংশন চালাই, আমরা মোট গণনা বৃদ্ধি করতে পারি এবং বর্তমান অনুরোধটি ট্র্যাক করতে বর্তমান সংখ্যাটি ক্যাপচার করতে পারি (" ")। totalRequestCount handleSubmit thisRequestNumber যখন একটি অনুরোধ সমাধান হয়, আমরা কনসোলে এর সংশ্লিষ্ট নম্বর লগ করতে পারি। fetch const form = document.querySelector('form'); form.addEventListener('submit', handleSubmit); let totalRequestCount = 0 function handleSubmit(event) { totalRequestCount += 1 const thisRequestNumber = totalRequestCount const form = event.currentTarget; fetch(form.action, { method: form.method, body: new FormData(form) }).then(() => { console.log(thisRequestNumber) }) event.preventDefault(); } এখন, যদি আমরা সেই সাবমিট বোতামটি কয়েকবার ভেঙে ফেলি, তাহলে আমরা দেখতে পারি যে কনসোলে বিভিন্ন সংখ্যা প্রিন্ট করা হয়েছে: 2, 3, 1, 4, 5। এটি নেটওয়ার্ক গতির উপর নির্ভর করে, কিন্তু আমি মনে করি আমরা সবাই একমত হতে পারি যে এটি আদর্শ নয়। একটি দৃশ্যকল্প বিবেচনা করুন যেখানে একজন ব্যবহারকারী পর্যায়ক্রমে বেশ কয়েকটি অনুরোধ ট্রিগার করে এবং সম্পূর্ণ হওয়ার পরে, আপনার অ্যাপ্লিকেশন তাদের পরিবর্তনগুলির সাথে পৃষ্ঠাটি আপডেট করে। ক্রমবর্ধমান অনুরোধগুলি সমাধান করার কারণে ব্যবহারকারী শেষ পর্যন্ত ভুল তথ্য দেখতে পারে। fetch এটি নন-জাভাস্ক্রিপ্ট বিশ্বে একটি অ-ইস্যু কারণ ব্রাউজার পূর্ববর্তী যেকোনো অনুরোধ বাতিল করে এবং সাম্প্রতিক অনুরোধটি সম্পূর্ণ হওয়ার পরে পৃষ্ঠাটি লোড করে, সবচেয়ে আপ-টু-ডেট সংস্করণ লোড করে। কিন্তু পাতা রিফ্রেশ হিসাবে সেক্সি হয় না. জাভাস্ক্রিপ্ট প্রেমীদের জন্য ভাল খবর হল যে আমাদের উভয়ই থাকতে পারে এবং একটি সামঞ্জস্যপূর্ণ UI! সেক্সি ব্যবহারকারীর অভিজ্ঞতা আমাদের শুধু একটু বেশি কাজ করতে হবে। আপনি যদি API ডকুমেন্টেশন দেখেন, আপনি দেখতে পাবেন যে ব্যবহার করে ফেচ বাতিল করা সম্ভব এবং বিকল্পগুলির সম্পত্তি। এটা এই মত কিছু দেখায়: fetch AbortController fetch signal const controller = new AbortController(); fetch(url, { signal: controller.signal }); অনুরোধে এর সংকেত প্রদান করে, এর পদ্ধতিটি ট্রিগার হলে আমরা অনুরোধটি বাতিল করতে পারি। fetch AbortContoller AbortContoller abort আপনি জাভাস্ক্রিপ্ট কনসোলে একটি পরিষ্কার উদাহরণ দেখতে পারেন। একটি তৈরি করার চেষ্টা করুন, অনুরোধ শুরু করুন, তারপর অবিলম্বে পদ্ধতিটি কার্যকর করুন। AbortController fetch abort const controller = new AbortController(); fetch('', { signal: controller.signal }); controller.abort() আপনি অবিলম্বে কনসোলে মুদ্রিত একটি ব্যতিক্রম দেখতে হবে. ক্রোমিয়াম ব্রাউজারগুলিতে, এটি বলা উচিত, "অপরাধিত (প্রতিশ্রুতিতে) DOMexception: ব্যবহারকারী একটি অনুরোধ বাতিল করেছে।" এবং আপনি যদি নেটওয়ার্ক ট্যাবটি অন্বেষণ করেন, তাহলে আপনি স্ট্যাটাস টেক্সট "(বাতিল)" সহ একটি ব্যর্থ অনুরোধ দেখতে পাবেন৷ এটি মাথায় রেখে, আমরা আমাদের ফর্মের জমা হ্যান্ডলারে একটি যোগ করতে পারি। যুক্তি নিম্নরূপ হবে: AbortController প্রথমত, পূর্ববর্তী কোনো অনুরোধের জন্য একটি চেক করুন। যদি একটি বিদ্যমান থাকে, এটি বাতিল করুন. AbortController পরবর্তী, বর্তমান অনুরোধের জন্য একটি তৈরি করুন যা পরবর্তী অনুরোধে বাতিল করা যেতে পারে। AbortController অবশেষে, যখন একটি অনুরোধ সমাধান হয়ে যায়, তখন এর সংশ্লিষ্ট সরিয়ে দিন। AbortController এটি করার বিভিন্ন উপায় রয়েছে, তবে আমি প্রতিটি জমা দেওয়া DOM নোড এবং এর সংশ্লিষ্ট এর মধ্যে সম্পর্ক সংরক্ষণ করতে একটি ব্যবহার করব। যখন একটি ফর্ম জমা দেওয়া হয়, আমরা সেই অনুযায়ী চেক এবং আপডেট করতে পারি। <form> AbortController WeakMap WeakMap const pendingForms = new WeakMap(); function handleSubmit(event) { const form = event.currentTarget; const previousController = pendingForms.get(form); if (previousController) { previousController.abort(); } const controller = new AbortController(); pendingForms.set(form, controller); fetch(form.action, { method: form.method, body: new FormData(form), signal: controller.signal, }).then(() => { pendingForms.delete(form); }); event.preventDefault(); } const forms = document.querySelectorAll('form'); for (const form of forms) { form.addEventListener('submit', handleSubmit); } মূল জিনিসটি একটি গর্ভপাত কন্ট্রোলারকে তার সংশ্লিষ্ট ফর্মের সাথে সংযুক্ত করতে সক্ষম হচ্ছে। ফর্মের DOM নোডটিকে এর কী হিসাবে ব্যবহার করা এটি করার একটি সুবিধাজনক উপায়। WeakMap এটির সাথে, আমরা অনুরোধে এর সংকেত যোগ করতে পারি, কোনো পূর্ববর্তী নিয়ন্ত্রক বাতিল করতে পারি, নতুন যোগ করতে পারি এবং সম্পূর্ণ হওয়ার পরে সেগুলি মুছে ফেলতে পারি। fetch AbortController আশা করি, যে সব অর্থে তোলে. এখন, যদি আমরা সেই ফর্মের সাবমিট বোতামটি কয়েকবার ছিঁড়ে ফেলি, আমরা দেখতে পাব যে সাম্প্রতিকতমটি ছাড়া সমস্ত API অনুরোধ বাতিল হয়ে যাবে। এর মানে হল যে কোনো ফাংশন সেই HTTP প্রতিক্রিয়ায় সাড়া দিয়ে আপনার প্রত্যাশা অনুযায়ী আরও বেশি আচরণ করবে। এখন, যদি আমরা উপরে আমাদের একই কাউন্টিং এবং লগিং লজিক ব্যবহার করি, তাহলে আমরা সাবমিট বোতামটি সাতবার স্মাশ করতে পারি এবং কনসোলে ছয়টি ব্যতিক্রম ( এর কারণে) এবং একটি লগ "7" দেখতে পাব। AbortController যদি আমরা আবার জমা দেই এবং অনুরোধটি সমাধানের জন্য পর্যাপ্ত সময় দেয়, তাহলে আমরা কনসোলে "8" দেখতে পাব। এবং যদি আমরা সাবমিট বোতামটি গুচ্ছ গুচ্ছ করে ফেলি, আবার, আমরা সঠিক ক্রমে ব্যতিক্রম এবং চূড়ান্ত অনুরোধ গণনা দেখতে পাব। আপনি যদি একটি অনুরোধ বাতিল করার সময় কনসোলে DOM-এর ব্যতিক্রমগুলি দেখা এড়াতে আরও কিছু যুক্তি যোগ করতে চান, আপনি আপনার অনুরোধের পরে একটি ব্লক যোগ করতে পারেন এবং ত্রুটিটির নাম " " এর সাথে মেলে কিনা তা পরীক্ষা করতে পারেন: fetch .catch() AbortError fetch(url, { signal: controller.signal, }).catch((error) => { // If the request was aborted, do nothing if (error.name === 'AbortError') return; // Otherwise, handle the error here or throw it back to the console throw error }); বন্ধ এই পুরো পোস্টটি জাভাস্ক্রিপ্ট-বর্ধিত ফর্মগুলিতে ফোকাস করা হয়েছিল, তবে আপনি যখনই একটি অনুরোধ তৈরি করেন তখন একটি অন্তর্ভুক্ত করা সম্ভবত একটি ভাল ধারণা। এটি সত্যিই খুব খারাপ এটি ইতিমধ্যেই এপিআই-এর মধ্যে তৈরি করা হয়নি। কিন্তু আশা করি, এটি আপনাকে এটি অন্তর্ভুক্ত করার জন্য একটি ভাল পদ্ধতি দেখায়। fetch AbortController এটিও উল্লেখ করার মতো যে এই পদ্ধতিটি ব্যবহারকারীকে সাবমিট বোতামটি একগুচ্ছ বার স্প্যাম করা থেকে বাধা দেয় না। বোতামটি এখনও ক্লিকযোগ্য, এবং অনুরোধটি এখনও বন্ধ হয়ে যায়, এটি প্রতিক্রিয়াগুলির সাথে মোকাবিলা করার আরও সামঞ্জস্যপূর্ণ উপায় প্রদান করে। দুর্ভাগ্যবশত, যদি একজন ব্যবহারকারী একটি জমা বোতাম স্প্যাম , সেই অনুরোধগুলি এখনও আপনার ব্যাকএন্ডে যাবে এবং অপ্রয়োজনীয় সংস্থানগুলির একটি গুচ্ছ ব্যবহার করতে পারে। করে কিছু নিষ্পাপ সমাধান সাবমিট বোতামটি অক্ষম করতে পারে, একটি ব্যবহার করে , অথবা পূর্ববর্তীগুলি সমাধান করার পরে শুধুমাত্র নতুন অনুরোধ তৈরি করা। আমি এই বিকল্পগুলি পছন্দ করি না কারণ তারা ব্যবহারকারীর অভিজ্ঞতাকে ধীর করার উপর নির্ভর করে এবং শুধুমাত্র ক্লায়েন্টের দিকে কাজ করে। debounce তারা স্ক্রিপ্টেড অনুরোধের মাধ্যমে অপব্যবহারকে সম্বোধন করে না। আপনার সার্ভারে অনেক অনুরোধ থেকে অপব্যবহার মোকাবেলা করতে, আপনি সম্ভবত কিছু সেট আপ করতে চান . এটি এই পোস্টের সুযোগের বাইরে যায়, তবে এটি উল্লেখ করার মতো ছিল। হার সীমিত এটাও উল্লেখ করার মতো যে হার সীমিত করা ডুপ্লিকেট অনুরোধ, রেসের অবস্থা এবং অসঙ্গতিপূর্ণ UI আপডেটের মূল সমস্যার সমাধান করে না। আদর্শভাবে, আমরা উভয় প্রান্ত আবরণ উভয় ব্যবহার করা উচিত. যাইহোক, আমি আজকের জন্য এটিই পেয়েছি। আপনি যদি এই একই বিষয় কভার করে এমন একটি ভিডিও দেখতে চান তবে এটি দেখুন। https://www.youtube.com/watch?v=w8ZIoLnh1Dc&embedable=true পড়ার জন্য আপনাকে অনেক ধন্যবাদ. আপনি যদি এই নিবন্ধটি পছন্দ করেন, অনুগ্রহ করে . এটা আমাকে সমর্থন করার সেরা উপায় এক. আপনি এটিও করতে পারেন বা আপনি জানতে চান যখন নতুন নিবন্ধ প্রকাশিত হয়. এটা ভাগ করে নিন আমার নিউজলেটার জন্য সাইন আপ করুন আমাকে টুইটার এ অনুসরন কর মূলত প্রকাশিত austingil.com .