প্রতিশ্রুতি শৃঙ্খলে সেটটাইমআউট ব্যবহার


115

এখানে আমি প্রতিশ্রুতিগুলি ঘিরে আমার মাথা মোড়ানোর চেষ্টা করছি first প্রথম অনুরোধে এখানে আমি লিঙ্কগুলির একটি সেট আনছি next এবং পরবর্তী অনুরোধে আমি প্রথম লিঙ্কটির সামগ্রী আনব ut তবে পরবর্তী প্রতিশ্রুতি অবজেক্টটি ফেরার আগে আমি বিলম্ব করতে চাই o তাই আমি ব্যবহার করি এটিতে সেটটাইমআউট.কিন্তু এটি আমাকে নীচের জেএসওন ত্রুটি দেয় ( without setTimeout() it works just fine)

সিনট্যাক্সেরর: JSON.parse: JSON ডেটার 1 কলাম 1 লাইনে অপ্রত্যাশিত অক্ষর

আমি জানতে চাই কেন এটি ব্যর্থ হয়?

let globalObj={};
function getLinks(url){
    return new Promise(function(resolve,reject){

       let http = new XMLHttpRequest();
       http.onreadystatechange = function(){
            if(http.readyState == 4){
              if(http.status == 200){
                resolve(http.response);
              }else{
                reject(new Error());
              }
            }           
       }
       http.open("GET",url,true);
       http.send();
    });
}

getLinks('links.txt').then(function(links){
    let all_links = (JSON.parse(links));
    globalObj=all_links;

    return getLinks(globalObj["one"]+".txt");

}).then(function(topic){


    writeToBody(topic);
    setTimeout(function(){
         return getLinks(globalObj["two"]+".txt"); // without setTimeout it works fine 
         },1000);
});

1
নোট যে returnফাংশন নির্দিষ্ট, এবং শুধুমাত্র প্যারেন্ট ফাংশন ফিরে, এবং আপনি একটি async পদ্ধতি থেকে ফিরে আসতে পারবেন না।
অ্যাডিনিও

2
লক্ষ্য করুন যে এ কোডটি ব্যবহারের চেয়ে কাঠামোর আরও অনেক ভাল উপায় আছে globalObj
বার্গি

কোথায় JSON.parseফেলে দেয়? আমি বিশ্বাস setTimeoutকরতে thenঅসুবিধে হয়েছি যে একটিতে একটি কলব্যাক পূর্ববর্তী thenকলব্যাকের কলকে প্রভাবিত করে ।
বার্গি

উত্তর:


191

প্রতিশ্রুতি শৃঙ্খলা অব্যাহত রাখতে, আপনি setTimeout()যেভাবে করেছিলেন সেভাবে আপনি ব্যবহার করতে পারবেন না কারণ আপনি .then()হ্যান্ডলারের কাছ থেকে কোনও প্রতিশ্রুতি ফিরিয়ে দিচ্ছেন না - আপনি setTimeout()কলব্যাক থেকে এটি ফিরিয়ে দিচ্ছেন যা আপনার কোনও ভাল নয়।

পরিবর্তে, আপনি এর মতো একটি সাধারণ সামান্য বিলম্ব কার্যকারিতা তৈরি করতে পারেন:

function delay(t, v) {
   return new Promise(function(resolve) { 
       setTimeout(resolve.bind(null, v), t)
   });
}

এবং, তারপরে এটি ব্যবহার করুন:

getLinks('links.txt').then(function(links){
    let all_links = (JSON.parse(links));
    globalObj=all_links;

    return getLinks(globalObj["one"]+".txt");

}).then(function(topic){
    writeToBody(topic);
    // return a promise here that will be chained to prior promise
    return delay(1000).then(function() {
        return getLinks(globalObj["two"]+".txt");
    });
});

এখানে আপনি .then()হ্যান্ডলারের কাছ থেকে একটি প্রতিশ্রুতি ফিরিয়ে দিচ্ছেন এবং সুতরাং এটি যথাযথভাবে শিকলযুক্ত।


আপনি প্রতিশ্রুতি বস্তুতে একটি বিলম্ব পদ্ধতিও যুক্ত করতে পারেন এবং তারপরে সরাসরি .delay(x)আপনার প্রতিশ্রুতিগুলিতে কোনও পদ্ধতি ব্যবহার করতে পারেন:

function delay(t, v) {
   return new Promise(function(resolve) { 
       setTimeout(resolve.bind(null, v), t)
   });
}

Promise.prototype.delay = function(t) {
    return this.then(function(v) {
        return delay(t, v);
    });
}


Promise.resolve("hello").delay(500).then(function(v) {
    console.log(v);
});

অথবা, ব্লুবার্ড প্রতিশ্রুতি গ্রন্থাগার ব্যবহার করুন যা ইতিমধ্যে .delay()বিল্ট ইন পদ্ধতি রয়েছে has


1
রেজোলিউশন ফাংশনটি তখন () এর ভিতরে ফাংশন হয় .. সুতরাং সেটটাইমআউট (সমাধান, টি) মানে সেটটাইমআউট (ফাংশন () .... রিটার্ন ....}, টি) তাই না ... তবে এটি কেন কাজ করবে?
AL-zami

2
@ আ-জামি - delay()একটি প্রতিশ্রুতি দেয় যা এর পরে সমাধান হবে setTimeout()
jفر00

সহজেই কোনও প্রতিশ্রুতি বিলম্ব করতে সেটটাইমআউটের জন্য আমি একটি প্রতিশ্রুতি মোড়ক তৈরি করেছি। github.com/zengfenfei/delay
কেভিন

4
@ পিডিএম - vহ'ল একটি alচ্ছিক মান যা আপনি বিলম্ব প্রতিশ্রুতি দিয়ে সমাধান করতে চান এবং এইভাবে প্রতিশ্রুতি শৃঙ্খলাবদ্ধ করে দিন। resolve.bind(null, v)হয় জায়গা function() {resolve(v);} হয় হয় কাজ করবে।
jਫਰ00

আপনাকে অনেক ধন্যবাদ ... প্রোটোটাইপ বিলম্ব কাজ করেছে তবে ফাংশনটি >>> নয় then টি অপরিবর্তিত ছিল।
খ্রিস্টান ম্যাথু

75
.then(() => new Promise((resolve) => setTimeout(resolve, 15000)))

হালনাগাদ:

যখন আমার async ফাংশনটিতে ঘুম দরকার তখন আমি ফেলে ফেলি

await new Promise(resolve => setTimeout(resolve, 1000))

আপনি কি ঠিক এর মতো একটি অ্যাসিঙ্ক ফাংশনটিতে ঘুমাতে পারেন না? নতুন প্রতিশ্রুতির জন্য অপেক্ষা করুন (সমাধান => সেটটাইমআউট (সমাধান, 1000));
অ্যান্টনি মুন বিম টুরি

@ অ্যান্টনিমুনবিম টুরি স্থির, টাই
ইগোর করসাকভ

52

উত্তরের সংক্ষিপ্ত ES6 সংস্করণ:

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

এবং তারপরে আপনি এটি করতে পারেন:

delay(3000).then(() => console.log('Hello'));

এবং যদি আপনার rejectবিকল্পের প্রয়োজন হয় , যেমন এসিলিন্ট বৈধতার জন্য, তবেconst delay = ms => new Promise((resolve, reject) => setTimeout(resolve, ms))
ডেভিড থমাস

10

আপনি যদি একটি ভিতরে হন .then () ব্লক এবং আপনি একটি চালানো চান settimeout ()

            .then(() => {
                console.log('wait for 10 seconds . . . . ');
                return new Promise(function(resolve, reject) { 
                    setTimeout(() => {
                        console.log('10 seconds Timer expired!!!');
                        resolve();
                    }, 10000)
                });
            })
            .then(() => {
                console.log('promise resolved!!!');

            })

আউটপুট নীচে প্রদর্শিত হবে

wait for 10 seconds . . . .
10 seconds Timer expired!!!
promise resolved!!!

শুভ কোডিং!


-1

নোড.জেজে আপনি নিম্নলিখিতগুলিও করতে পারেন:

const { promisify } = require('util')
const delay = promisify(setTimeout)

delay(1000).then(() => console.log('hello'))

আমি এটি চেষ্টা করে দেখেছি এবং বিলম্বের ফাংশনের মধ্যে 0 টি প্রত্যাশিত আর্গুমেন্ট পেয়েছি।
অ্যালেক্স রিন্ডোন

আমি এটি নোড.জেজেস 8, 10, 12, 13 এ কাজ করে তা নিশ্চিত করতে পারি utilyou're আপনি একটি বান্ডলার বা কিছু ব্যবহার করছেন?
জানুয়ারী
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.