यदि ब्राउज़र देशी वादों का समर्थन नहीं करता है, तो एक माइक्रोटैस्क को कैसे कतारबद्ध करें?


11

कोड लिखना बेहतर होता है जो तत्काल कॉलबैक (जैसे कि माइक्रोट्स्क बनाम मैक्रोटस्क) के समय पर निर्भर नहीं करता है, लेकिन चलो उस समय के लिए अलग रख दें।

setTimeoutएक मैक्रोटस्क को कतारबद्ध करता है, जो कि कम से कम, सभी माइक्रोटेस्क (और माइक्रोटेस्क कि वे स्पॉन को पूरा करते हैं) तक शुरू होने का इंतजार करते हैं। यहाँ एक उदाहरण है:

console.log('Macrotask queued');
setTimeout(function() {
  console.log('Macrotask running');
});
Promise.resolve()
  .then(function() {
    console.log('Microtask running');
  });
console.log('Microtask queued');
console.log('Last line of script');

एक के व्यवहार .thenएक संकल्प लिया वादा पर तत्काल के व्यवहार से मौलिक रूप से अलग है setTimeoutकॉलबैक - वादा .thenपहले चलेंगे, भले ही setTimeoutपहले कतारबद्ध किया गया था। लेकिन केवल आधुनिक ब्राउज़र वादा का समर्थन करते हैं। यदि मौजूद नहीं है तो माइक्रोटस्क की विशेष कार्यक्षमता को ठीक से कैसे पॉलीफ़िल किया जा सकता Promiseहै?

यदि आप .thenका उपयोग करके एक microtask की नकल करने की कोशिश करते हैं setTimeout, तो आप एक macrotask कतारबद्ध करेंगे, न कि एक microtask, इसलिए बुरी तरह से .thenपॉलीफ़िल्ड सही समय पर नहीं चलेगा अगर एक macrotask पहले से ही पंक्तिबद्ध है।

वहाँ एक समाधान का उपयोग कर रहा है MutationObserver, लेकिन यह बदसूरत लग रहा है, और क्या MutationObserverहै के लिए नहीं है। इसके अलावा, MutationObserverIE10 और इससे पहले समर्थित नहीं है। यदि कोई ऐसे वातावरण में माइक्रोटस्क को कतारबद्ध करना चाहता है जो मूल रूप से वादों का समर्थन नहीं करता है, तो क्या कोई बेहतर विकल्प हैं?

(मैं वास्तव में IE10 का समर्थन करने की कोशिश नहीं कर रहा हूं - यह सिर्फ एक सैद्धांतिक अभ्यास है कि कैसे वादे के बिना माइक्रोटेक को कतार में रखा जा सकता है)


1
मेरा सुझाव है कि वादे के क्रियान्वयन पर एक नज़र डालें जो प्रदर्शन-उन्मुख हैं, विशेष रूप से ब्लूबर्ड। इसके इतिहासschedule.js पर एक नज़र डालते हुए ज्ञानवर्धक होगा।
बर्गी

क्या आपने कोर-जेएस जैसी किसी चीज़ का उपयोग करके वादा करने की कोशिश की है?
ह्यूगो

जवाबों:


4

अगर हम IE के बारे में बात कर रहे हैं तो आप उपयोग कर सकते हैं setImmediate

https://developer.mozilla.org/en-US/docs/Web/API/Window/setImmediate

इसके अलावा, IE10 और इससे पहले के MutationObserver को सपोर्ट नहीं किया गया है।

setImmediateIE10 पर समर्थित है। तो प्लस एक IE संस्करण।
और, यदि आपकी रुचि है, तो Node.js.

MutationObserver का उपयोग करके एक समाधान है, लेकिन यह बदसूरत दिखता है, और MutationObserver के लिए ऐसा नहीं है।

अन्य संभावित पॉलीफ़िल हैं, यहां कुछ कार्यान्वयन हैं: https://github.com/YuzuJS/setImmediate/blob/master/setImmediate.js (यह एमडीएन में उल्लेख किया गया है: https://github.com/taylorhakes/ setAsap / बूँद / मास्टर / setAsap.js (एक और अधिक सरल)

और लगभग सभी पॉलीफिल के रूप में वे बदसूरत हैं।

लेकिन वैसे भी, यहाँ इसका सार (पोस्टमैसेज का उपयोग करके) एक उदाहरण है, और मुझे लगता है कि यह कम से कम बदसूरत है (लेकिन यह भी एक सही पॉलीफ़िल नहीं है)

var setImmediate = (function() {
  var queue = [];

  function on_message(e) {
    if(e.data === "setImmediateMsg") queue.pop()()
  }

  if(window.addEventListener) { // IE9+
    window.addEventListener('message', on_message)
  } else { // IE8
    window.attachEvent('onmessage', on_message)
  }

  return function(fn) {
    queue.unshift(fn)
    window.postMessage("setImmediateMsg", "*")
  }
}())

setTimeout(function() {
  console.log('Macrotask running');
});
console.log('Macrotask queued');
setImmediate(function() {
  console.log('Microtask running');
});
console.log('Microtask queued');
console.log('Last line of script');


महान पाता है, मुझे वे सब पसंद हैं!
स्नो

@ वैसे, आपने कहा कि यह एक सैद्धांतिक अभ्यास है, लेकिन, मैं अभी भी उत्सुक हूं, कि आप 2019 में इस विचार के साथ कैसे आए?
x00

मैं बस सोच रहा था कि कैसे माइक्रोटेक्सेस को कतारबद्ध किया जा सकता है, वास्तव में कुछ अधिक विशिष्ट नहीं था। मैं इस तरह की उम्मीद कर रहा था कि भाषा में कुछ ऐसा बनाया गया है जो उन्हें प्रोमिस के अलावा अन्य तक पहुंच प्रदान करता है, लेकिन ऐसा लगता है कि ऐसा नहीं है। अन्य सभी तरीके पर्यावरण-विशिष्ट quirks को शामिल करना चाहते हैं जो उस तरह की चीज़ के लिए डिज़ाइन नहीं किए गए थे (लेकिन बस वैसे भी काम करने के लिए होता है)।
बर्फ

8

मैंने देखा कि mutationObserverकॉलबैक में माइक्रो-मास्क का उपयोग किया जाता है, और सौभाग्य से, IE11 इसका समर्थन करता है, इसलिए मुझे कॉलबैक को सहेजकर और फिर एक तत्व को बदलकर पर्यवेक्षक को ट्रिगर करने के लिए IE11 में एक माइक्रोटस्क को कतार में रखने का विचार था:

var weirdQueueMicrotask = (function() {
  var elementThatChanges = document.createElement('div');
  var callback;
  var bool = false;
  new MutationObserver(function() {
    callback();
  }).observe(elementThatChanges, { childList: true });
  return function(callbackParam) {
    callback = callbackParam;
    elementThatChanges.textContent = bool = !bool;
  };
})();

setTimeout(function() {
  console.log('Macrotask running');
});
console.log('Macrotask queued');
weirdQueueMicrotask(function() {
  console.log('Microtask running');
});
console.log('Microtask queued');
console.log('Last line of script');

आप IE11 खोल सकते हैं और उपरोक्त कार्य देख सकते हैं, लेकिन कोड अजीब लगता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.