সেটটাইমআউট থেকে কীভাবে প্রতিশ্রুতি করবেন


96

এটি রিয়েলওয়ার্ল্ড সমস্যা নয়, আমি কেবল প্রতিশ্রুতি তৈরি হয় তা বোঝার চেষ্টা করছি।

সেট টাইমআউটের মতো কোনও ফাংশন যা কিছুই দেয় না তার জন্য কীভাবে প্রতিশ্রুতি রাখতে হয় তা আমার বুঝতে হবে।

ধরুন আমার আছে:

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

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

আমি কীভাবে এমন প্রতিশ্রুতি তৈরি করব যা প্রস্তুত asyncহওয়ার পরে ফিরে আসতে setTimeoutপারে callback()?

আমার ধারণা ছিল এটি মোড়ানো আমাকে কোথাও নিয়ে যাবে:

function setTimeoutReturnPromise(){

    function promise(){}

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

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


    return promise;
}

তবে আমি এর বাইরে ভাবতে পারি না।


আপনি কি নিজের প্রতিশ্রুতি গ্রন্থাগার তৈরি করার চেষ্টা করছেন ?
টিজে ক্রোডার

@ টিজে ক্রাউডার আমি ছিলাম না তবে আমার ধারণা এখন এটিই আমি বুঝতে চেষ্টা করছিলাম। এটি একটি লাইব্রেরি কীভাবে এটি করবে
laggingreflex

@ পিছিয়ে পড়ে: বোঝায়, আমি উত্তরে মৌলিক প্রতিশ্রুতি বাস্তবায়নের একটি উদাহরণ যুক্ত করেছি।
টিজে ক্রোডার

আমি মনে করি এটি একটি খুব বাস্তব-বিশ্ব সমস্যা এবং আমার সংস্থাটি যে বিশাল প্রকল্প তৈরি করছে তার জন্য আমাকে একটি সমাধান করতে হয়েছিল। এটি করার সম্ভবত আরও ভাল উপায় ছিল তবে আমার ব্লুটুথ স্ট্যাকের জন্য আমাকে একটি প্রতিশ্রুতি সংশোধন করতে বিলম্ব করা প্রয়োজন। আমি কি করেছি তা দেখানোর জন্য নীচে পোস্ট করব।
রোদ-মিত্তাল

4
কেবল একটি নোট যে 2017 সালে 'অ্যাসিঙ্ক' কোনও ফাংশনটির জন্য কিছুটা বিভ্রান্তিকর নাম, যেমনটি আপনার হতে পারেasync function async(){...}
মাইকম্যাকানা

উত্তর:


132

আপডেট (2017)

এখানে 2017 সালে প্রতিশ্রুতিগুলি জাভাস্ক্রিপ্টে তৈরি করা হয়েছে, সেগুলি ES2015 স্পেস দ্বারা যুক্ত করা হয়েছিল (পলিফিলগুলি IE8-IE11 এর মতো পুরানো পরিবেশের জন্য উপলব্ধ)। তারা যে সিনট্যাক্সটি দিয়েছিল তাতে আপনি Promiseকন্সট্রাক্টর ( Promise নির্বাহক ) এর নিকটে যে কলব্যাক ব্যবহার করেছেন তা ব্যবহার করে যা আর্গুমেন্ট হিসাবে প্রতিশ্রুতি সমাধান / প্রত্যাখ্যান করার জন্য কার্যগুলি গ্রহণ করে।

প্রথমত, যেহেতু asyncএখন জাভাস্ক্রিপ্টটির একটি অর্থ রয়েছে (যদিও এটি কিছু নির্দিষ্ট প্রসঙ্গে কেবল একটি কীওয়ার্ড), আমি laterবিভ্রান্তি এড়াতে ফাংশনের নাম হিসাবে ব্যবহার করতে যাচ্ছি ।

বেসিক বিলম্ব

দেশীয় প্রতিশ্রুতি (বা বিশ্বস্ত পলিফিল) ব্যবহার করে এটি দেখতে এরকম দেখাবে:

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

মনে রাখবেন যে এটি ব্রাউজারগুলির সংজ্ঞারsetTimeout সাথে সামঞ্জস্যপূর্ণ এমন একটি সংস্করণ হিসাবে ধরেছে যেখানে setTimeoutআপনি বিরতি দেওয়ার পরে কলব্যাকের কোনও যুক্তি পাস না করে (এটি ব্রাউজার-নন পরিবেশে সত্য হতে পারে না, এবং আগেও ব্যবহৃত হত না) ফায়ারফক্সে সত্য, তবে এখন এটি; এটি ক্রোমে সত্য এবং এমনকি আইই 8 এ ফিরে আসে)।

মান সহ বেসিক বিলম্ব

যদি আপনি চান যে আপনার ফাংশনটি কোনও অস্পষ্ট-আধুনিক ব্রাউজারে বৈকল্পিকভাবে একটি রেজোলিউশন মানটি পাস করতে পারে যা আপনাকে setTimeoutবিলম্বের পরে অতিরিক্ত যুক্তি দিতে দেয় এবং তারপরে কল করার পরে কলব্যাকগুলিতে পাস করে, আপনি এটি করতে পারেন (বর্তমান ফায়ারফক্স এবং ক্রোম; আইই 11 + , সম্ভবত এজ; আই 8 বা আই 9 নয়, আই 10 10 সম্পর্কে ধারণা নেই):

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
}

প্রশ্নে একটি মন্তব্যে, আমি জিজ্ঞাসা করেছি:

আপনি কি নিজের প্রতিশ্রুতি গ্রন্থাগার তৈরি করার চেষ্টা করছেন?

এবং আপনি বলেছেন

আমি ছিলাম না তবে আমি এখন অনুমান করি আসলে এটিই আমি বুঝতে চেষ্টা করছিলাম। এটি কিভাবে একটি গ্রন্থাগার এটি করবে do

এই বোঝাপড়ার জন্য সহায়তা করার জন্য, এখানে একটি খুব মৌলিক উদাহরণ দেওয়া হয়েছে, যা দূর থেকে প্রতিশ্রুতি দেয় না: অনুগ্রহ করে লাইভ কপি

<!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>


আপনার উত্তর বাতিলকরণটি পরিচালনা করে না
আলেকজান্ডার ড্যানিলভ

@ আলেকজান্ডারডানিলভ: প্রতিশ্রুতি বাতিলযোগ্য নয়। আপনি অবশ্যই একটি ফাংশন লিখতে পারেন যা কোনও বাতিল পদ্ধতি এবং কোনও পৃথকভাবে প্রতিশ্রুতির জন্য একজন অ্যাক্সেসর ফেরত দিয়েছিল, তারপরে যদি বাতিল পদ্ধতিটি বলা হয় তবে প্রতিশ্রুতিটি প্রত্যাখ্যান করুন ...
টিজে ক্রাউডার

4
@ আলেকজান্ডারডানিলভ: আমি এগিয়ে গিয়ে একটি যুক্ত করেছি।
টিজে ক্রাউডার

1
const setTimeoutAsync = (cb, delay) =>
  new Promise((resolve) => {
    setTimeout(() => {
      resolve(cb());
    }, delay);
  });

আমরা এর মতো কাস্টম 'সিবি fxn' পাস করতে পারি 👆🏽


0

এটি মূল প্রশ্নের উত্তর নয়। তবে, আসল প্রশ্ন হিসাবে এটি একটি সমস্যা হওয়া উচিত নয় problem আমি একটি বন্ধুকে জাভাস্ক্রিপ্টের প্রতিশ্রুতিগুলি এবং প্রতিশ্রুতি এবং কলব্যাকের মধ্যে পার্থক্য বোঝানোর চেষ্টা করেছি।

নীচের কোডটি ব্যাখ্যা হিসাবে কাজ করে:

//very basic callback example using setTimeout
//function a is asynchronous function
//function b used as a callback
function a (callback){
    setTimeout (function(){
       console.log ('using callback:'); 
       let mockResponseData = '{"data": "something for callback"}'; 
       if (callback){
          callback (mockResponseData);
       }
    }, 2000);

} 

function b (dataJson) {
   let dataObject = JSON.parse (dataJson);
   console.log (dataObject.data);   
}

a (b);

//rewriting above code using Promise
//function c is asynchronous function
function c () {
   return new Promise(function (resolve, reject) {
     setTimeout (function(){
       console.log ('using promise:'); 
       let mockResponseData = '{"data": "something for promise"}'; 
       resolve(mockResponseData); 
    }, 2000);      
   }); 

}

c().then (b);

জেএসফিডাল

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.