javascript - सेटटाइमआउट[डुप्लीकेट]से एक वादा कैसे करें




settimeout promise (2)

इस प्रश्न का पहले से ही यहाँ एक उत्तर है:

यह एक वास्तविक समस्या नहीं है, मैं सिर्फ यह समझने की कोशिश कर रहा हूं कि वादे कैसे किए जाते हैं।

मुझे यह समझने की ज़रूरत है कि एक फ़ंक्शन के लिए एक वादा कैसे किया जाए जो सेटटाइमआउट की तरह कुछ भी नहीं लौटाता है।

मान लीजिए कि मेरे पास है:

function async(callback){ 
    setTimeout(function(){
        callback();
    }, 5000);
}

async(function(){
    console.log('async called back');
});

मैं एक वादा कैसे कर सकता हूं कि सेट setTimeout callback() के लिए तैयार होने के बाद setTimeout वापस आ सकता है?

मुझे लगा कि यह मुझे कहीं ले जाएगा:

function setTimeoutReturnPromise(){

    function promise(){}

    promise.prototype.then = function() {
        console.log('timed out');
    };

    setTimeout(function(){
        return ???
    },2000);


    return promise;
}

लेकिन मैं इससे आगे नहीं सोच सकता।


Answers

अपडेट (2017)

यहां 2017 में, प्रोमो को जावास्क्रिप्ट में बनाया गया है, उन्हें ES2015 कल्पना द्वारा जोड़ा गया था (पॉलीफ़िल IE8-IE11 जैसे पुराने वातावरण के लिए उपलब्ध हैं)। जिस वाक्य-विन्यास के साथ वे गए थे, वह एक कॉलबैक का उपयोग करता है जिसे आप Promise कंस्ट्रक्टर ( Promise एक्ज़ीक्यूटर ) में पास करते हैं जो वादे के रूप में वादे को अस्वीकार / अस्वीकार करने के लिए कार्य करता है।

पहले, चूंकि async अब जावास्क्रिप्ट में अर्थ है (भले ही यह कुछ संदर्भों में एक कीवर्ड है), मैं भ्रम से बचने के लिए फ़ंक्शन के नाम के रूप में later में उपयोग करने जा रहा हूं।

मूल विलंब

देशी वादों (या एक वफादार पॉलीफ़िल) का उपयोग करना इस तरह दिखेगा:

function later(delay) {
    return new Promise(function(resolve) {
        setTimeout(resolve, delay);
    });
}

ध्यान दें कि setTimeout का एक संस्करण मानता है जो ब्राउज़र के लिए परिभाषा के अनुरूप है जहां setTimeout कॉलबैक के लिए कोई भी तर्क पारित नहीं करता है जब तक कि आप अंतराल के बाद उन्हें न दें (यह गैर-ब्राउज़र वातावरण में सच नहीं हो सकता है, और इसका उपयोग नहीं किया गया है फ़ायरफ़ॉक्स पर सच हो, लेकिन अब है; यह क्रोम पर सच है और IE8 पर भी वापस)।

मूल्य के साथ बुनियादी देरी

यदि आप चाहते हैं कि आपका फ़ंक्शन वैकल्पिक रूप से किसी भी अस्पष्ट-आधुनिक ब्राउज़र पर एक रिज़ॉल्यूशन मान पारित करें, जो आपको देरी के बाद setTimeout लिए अतिरिक्त तर्क देने की अनुमति देता है और फिर कॉल करने पर उन लोगों को पास करता है, जो आप कर सकते हैं (वर्तमान फ़ायरफ़ॉक्स और क्रोम IE11 +, संभवतः बढ़त नहीं, IE8 या IE9; IE10 के बारे में कोई विचार नहीं):

function later(delay, value) {
    return new Promise(function(resolve) {
        setTimeout(resolve, delay, value); // Note the order, `delay` before `value`
        /* Or for outdated browsers that don't support doing that:
        setTimeout(function() {
            resolve(value);
        }, delay);
        Or alternately:
        setTimeout(resolve.bind(null, value), delay);
        */
    });
}

यदि आप ES2015 + तीर फ़ंक्शंस का उपयोग कर रहे हैं, तो यह अधिक संक्षिप्त हो सकता है:

function later(delay, value) {
    return new Promise(resolve => setTimeout(resolve, delay, value));
}

या और भी

const later = (delay, value) =>
    new Promise(resolve => setTimeout(resolve, delay, value));

मूल्य के साथ रद्द करने योग्य विलंब

यदि आप समय-सीमा रद्द करना संभव बनाना चाहते हैं, तो आप बस later में एक वादा वापस नहीं कर सकते, क्योंकि वादे रद्द नहीं किए जा सकते।

लेकिन हम एक वस्तु को cancel विधि और वादे के लिए एक सहायक के साथ आसानी से वापस कर सकते हैं, और रद्द करने पर वादे को अस्वीकार कर सकते हैं:

const later = (delay, value) => {
    let timer = 0;
    let reject = null;
    const promise = new Promise((resolve, _reject) => {
        reject = _reject;
        timer = setTimeout(resolve, delay, value);
    });
    return {
        get promise() { return promise; },
        cancel() {
            if (timer) {
                clearTimeout(timer);
                timer = 0;
                reject();
                reject = null;
            }
        }
    };
};

लाइव उदाहरण:

const later = (delay, value) => {
    let timer = 0;
    let reject = null;
    const promise = new Promise((resolve, _reject) => {
        reject = _reject;
        timer = setTimeout(resolve, delay, value);
    });
    return {
        get promise() { return promise; },
        cancel() {
            if (timer) {
                clearTimeout(timer);
                timer = 0;
                reject();
                reject = null;
            }
        }
    };
};

const l1 = later(100, "l1");
l1.promise
  .then(msg => { console.log(msg); })
  .catch(() => { console.log("l1 cancelled"); });

const l2 = later(200, "l2");
l2.promise
  .then(msg => { console.log(msg); })
  .catch(() => { console.log("l2 cancelled"); });
setTimeout(() => {
  l2.cancel();
}, 150);

मूल उत्तर 2014 से

आमतौर पर आपके पास एक वादा पुस्तकालय होगा (आप खुद को लिखते हैं, या वहां से कई में से एक)। उस पुस्तकालय में आमतौर पर एक वस्तु होगी जिसे आप बना सकते हैं और बाद में "हल" कर सकते हैं, और उस वस्तु में एक "वादा" होगा जिसे आप उससे प्राप्त कर सकते हैं।

फिर later कुछ इस तरह देखना चाहेंगे:

function later() {
    var p = new PromiseThingy();
    setTimeout(function() {
        p.resolve();
    }, 2000);

    return p.promise(); // Note we're not returning `p` directly
}

सवाल पर एक टिप्पणी में, मैंने पूछा:

क्या आप अपना खुद का वादा पुस्तकालय बनाने की कोशिश कर रहे हैं?

और तुमने कहा था

मैं नहीं था, लेकिन मुझे लगता है कि अब वास्तव में वही है जो मैं समझने की कोशिश कर रहा था। कि एक पुस्तकालय यह कैसे करेगा

उस समझ की सहायता के लिए, यहाँ एक बहुत ही मूल उदाहरण है, जो दूरस्थ रूप से वादा-ए का अनुपालन नहीं करता है: लाइव कॉपी

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Very basic promises</title>
</head>
<body>
  <script>
    (function() {

      // ==== Very basic promise implementation, not remotely Promises-A compliant, just a very basic example
      var PromiseThingy = (function() {

        // Internal - trigger a callback
        function triggerCallback(callback, promise) {
          try {
            callback(promise.resolvedValue);
          }
          catch (e) {
          }
        }

        // The internal promise constructor, we don't share this
        function Promise() {
          this.callbacks = [];
        }

        // Register a 'then' callback
        Promise.prototype.then = function(callback) {
          var thispromise = this;

          if (!this.resolved) {
            // Not resolved yet, remember the callback
            this.callbacks.push(callback);
          }
          else {
            // Resolved; trigger callback right away, but always async
            setTimeout(function() {
              triggerCallback(callback, thispromise);
            }, 0);
          }
          return this;
        };

        // Our public constructor for PromiseThingys
        function PromiseThingy() {
          this.p = new Promise();
        }

        // Resolve our underlying promise
        PromiseThingy.prototype.resolve = function(value) {
          var n;

          if (!this.p.resolved) {
            this.p.resolved = true;
            this.p.resolvedValue = value;
            for (n = 0; n < this.p.callbacks.length; ++n) {
              triggerCallback(this.p.callbacks[n], this.p);
            }
          }
        };

        // Get our underlying promise
        PromiseThingy.prototype.promise = function() {
          return this.p;
        };

        // Export public
        return PromiseThingy;
      })();

      // ==== Using it

      function later() {
        var p = new PromiseThingy();
        setTimeout(function() {
          p.resolve();
        }, 2000);

        return p.promise(); // Note we're not returning `p` directly
      }

      display("Start " + Date.now());
      later().then(function() {
        display("Done1 " + Date.now());
      }).then(function() {
        display("Done2 " + Date.now());
      });

      function display(msg) {
        var p = document.createElement('p');
        p.innerHTML = String(msg);
        document.body.appendChild(p);
      }
    })();
  </script>
</body>
</html>

जावास्क्रिप्ट

 var str = "My big string contain apples and oranges";
 var n = str.indexOf("apples"); 
 alert(n); //will alert 22, -1 if not found

jQuery

  <p>My big string contain apples and oranges</p>
  alert($("p:contains(apples)")[0] != undefined); //will alert true if found




javascript settimeout promise