1. प्रश्न
एक पेज ऑफ़लाइन इंडेक्स को पार्स करने और अगले पेज को प्रीफ़ेच करने के दौरान यूज़र द्वारा टाइप करते ही सर्च रिज़ल्ट्स को अपडेट करता है। Prioritized Task Scheduling API का उपयोग करके एक टास्क लेयर डिज़ाइन करें: बैकग्राउंड प्रीफ़ेच द्वारा इनपुट को ब्लॉक किए बिना विज़िबल अपडेट तुरंत चलने चाहिए। scheduler.postTask(), scheduler.yield(), कैंसिलेशन सिग्नल्स और API अनुपलब्ध होने पर व्यवहार की व्याख्या करें।
2. बाधाएं और स्पष्टीकरण
- सभी टास्क एक विंडो या Worker इवेंट लूप में चलते हैं; एक लंबा सिंक्रोनस फ़ंक्शन अभी भी उस थ्रेड को ब्लॉक करता है।
- काम को कम से कम
user-blocking,user-visible, औरbackgroundप्रायोरिटीज़ में वर्गीकृत करें। - स्क्रॉलिंग, रूट परिवर्तन, या नया इनपुट काम को अप्रचलित (obsolete) बना सकता है, इसलिए इसे कैंसिलेबल या री-प्रायोरिटाइज़ करने योग्य होना चाहिए।
- एक कार्यशील फॉलबैक रखें; व्यावसायिक शुद्धता ब्राउज़र समर्थन पर निर्भर नहीं हो सकती।
3. मुख्य दृष्टिकोण
scheduler.postTask(callback, options) एक प्रायोरिटी के साथ कॉलबैक को कतारबद्ध (queue) करता है और एक Promise लौटाता है। priority user-blocking, user-visible, या background हो सकता है। कैंसिल करने के लिए एक AbortSignal पास करें; एक शेयर्ड TaskController उस टास्क की प्रायोरिटी को भी बदल सकता है जो अभी शुरू नहीं हुआ है। scheduler.yield() एक एसिंक फ़ंक्शन को आगे बढ़ने से पहले स्वेच्छा से ब्राउज़र को कंट्रोल वापस लौटाने की अनुमति देता है।
प्रायोरिटी क्रम को बदलती है; यह पहले से चल रहे JavaScript को प्रीएम्प्ट नहीं करती है। प्रत्येक कॉलबैक को छोटा रखें और चंक्स के बीच यील्ड (yield) करें। जब API अनुपलब्ध हो, तो समान कैंसिलेशन और पुराने-परिणाम (stale-result) सेमेंटिक्स को बनाए रखते हुए, छोटे setTimeout या MessageChannel बैचों, या किसी मौजूदा फ़्रेमवर्क शेड्यूलर का उपयोग करें।
4. संदर्भ कार्यान्वयन
const scheduler = globalThis.scheduler;
function scheduleWork(task, priority, signal) {
if (scheduler?.postTask) {
return scheduler.postTask(task, { priority, signal });
}
return new Promise((resolve, reject) => {
const run = () => {
if (signal?.aborted) {
reject(signal.reason);
return;
}
Promise.resolve().then(task).then(resolve, reject);
};
setTimeout(run, priority === "background" ? 50 : 0);
});
}
async function indexInChunks(items, signal) {
for (let i = 0; i < items.length; i += 100) {
await scheduleWork(() => buildIndex(items.slice(i, i + 100)),
"background", signal);
if (scheduler?.yield && i + 100 < items.length) {
await scheduler.yield({ signal });
}
}
}5. प्रदर्शन और शुद्धता
प्रायोरिटी प्रोग्राम के परिणामों को नहीं बदलती है या चल रहे कॉलबैक को बाधित नहीं करती है; यह केवल उन टास्क के सापेक्ष क्रम को प्रभावित करती है जो अभी शुरू नहीं हुए हैं। scheduler.postTask() से मिलने वाला Promise कॉलबैक के रिटर्न वैल्यू के साथ सेटल होता है, जबकि कॉलबैक त्रुटियों या कैंसिलेशन को कॉलर द्वारा रिजेक्शन के रूप में संभाला जाना चाहिए।
वास्तविक प्रदर्शन सीमा टास्क की अवधि और कुल कार्य है: 200 ms का सिंक्रोनस लूप लो-प्रायोरिटी कतार में रखे जाने पर भी इनपुट को ब्लॉक करता है। प्रति बैच Long Tasks, इनपुट डिले और कैंसिलेशन हिट रेट को मापें, फिर चंक के आकार को ट्यून करें। CPU-हैवी काम जो समानांतर में चल सकता है, वह Worker का हो सकता है; केवल प्रायोरिटी मेन-थ्रेड भुखमरी (starvation) को नहीं छिपा सकती।
6. फॉलो-अप और जाल
- ब्राउज़र ब्रांड या वर्ज़न से समर्थन का अनुमान लगाने के बजाय
globalThis.scheduler?.postTaskका पता लगाएं। - एक
AbortSignalउस काम को कैंसिल करता है जो शुरू नहीं हुआ है या जो सिग्नल को देखता है; यह पहले से चल रहे सिंक्रोनस कॉलबैक को जबरन रोक नहीं सकता है। - डायनेमिक प्रायोरिटी प्रीएम्प्शन नहीं है। यदि कोई टास्क पहले ही कतार छोड़ चुका है, तो पुराने परिणामों को कमिट करने से बचने के लिए व्यावसायिक-स्तर के वर्ज़न चेक का उपयोग करें।
- एक
setTimeoutफॉलबैक सभी नेटिव प्रायोरिटी सेमेंटिक्स को पुन: प्रस्तुत नहीं कर सकता है, इसलिए विज़िबल वर्क, बैकग्राउंड वर्क और कैंसिलेशन पाथ्स को स्पष्ट रूप से सत्यापित करें।
7. आगे पढ़ना
scheduler.postTask() की तुलना requestIdleCallback(), MessageChannel, और फ़्रेमवर्क शेड्यूलर्स से करें: पहला स्पष्ट प्रायोरिटी और कैंसिलेशन प्रदान करता है, आइडल कॉलबैक आइडल अवसरों पर निर्भर करते हैं, मैसेज चैनल केवल काम को कतारबद्ध करते हैं, और फ़्रेमवर्क कॉम्पोनेन्ट-लाइफ़साइकिल सेमेंटिक्स जोड़ सकते हैं। कम्पैटिबिलिटी, टास्क के प्रकार और मापे गए व्यवहार का उपयोग करके चुनें।
8. इंटरव्यू स्कोरिंग बिंदु
प्रायोरिटी सीमाओं की व्याख्या कर सकते हैं
उम्मीदवार को तीन प्रायोरिटीज़, लौटाए गए Promise, और इस तथ्य को कवर करना चाहिए कि केवल अभी तक शुरू न हुए टास्क ही क्रमित होते हैं; यह थ्रेड प्रीएम्प्शन नहीं है।
कैंसिलेबल काम डिज़ाइन कर सकते हैं
उन्हें AbortSignal या TaskController का उपयोग करना चाहिए, यह समझाना चाहिए कि शुरू किए गए कॉलबैक को जबरन नहीं रोका जा सकता है, और पुराने-परिणाम वर्ज़न चेक जोड़ना चाहिए।
एक प्रोग्रेसिव फॉलबैक लिख सकते हैं
उन्हें पहले फ़ीचर-डिटेक्ट करना चाहिए, फिर टास्क क्लासेस और कैंसिलेशन व्यवहार को बनाए रखते हुए टाइमर, मैसेज-चैनल या फ़्रेमवर्क शेड्यूलिंग प्रदान करना चाहिए।
डेटा के साथ लाभ साबित कर सकते हैं
उन्हें Long Tasks, इनपुट डिले, चंक अवधि और कैंसिलेशन हिट रेट को मापना चाहिए, और यह पहचानना चाहिए कि Workers वास्तव में CPU-हैवी काम को अलग करते हैं।