जावास्क्रिप्ट में सो जाओ - कार्यों के बीच देरी


129

वहाँ एक रास्ता है कि मैं जावास्क्रिप्ट में एक नींद कर सकता हूँ इससे पहले कि यह एक और कार्रवाई करता है?

उदाहरण:

 var a = 1+3;
 // Sleep 3 seconds before the next action here
 var b = a + 4;

जवाबों:


140

आप setTimeoutएक समान प्रभाव प्राप्त करने के लिए उपयोग कर सकते हैं :

var a = 1 + 3;
var b;
setTimeout(function() {
    b = a + 4;
}, (3 * 1000));

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


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

5
इस सवाल का जवाब नहीं है। सवाल एक "नींद" के बराबर पूछता है जो यह नहीं है।
felwithe

हालाँकि यह उत्तर इस बात से मेल नहीं खाता है कि प्रश्न क्या पूछा गया है, लेकिन यह लूप की तुलना में अधिक उपयोगी है और Date.now () की तुलना करें। कोई भी लागू नींद को अवरुद्ध लूप का उपयोग करने के लिए नहीं करता है।
ली चुनलिन

2
जब तक, ज़ाहिर है, एक अवरुद्ध लूप बिल्कुल वही है जो कोई चाहता है।
Wonko साने

55

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

function pauseBrowser(millis) {
    var date = Date.now();
    var curDate = null;
    do {
        curDate = Date.now();
    } while (curDate-date < millis);
}

new Date()जब तक आप मेमोरी, प्रोसेसिंग पावर, बैटरी और संभवतः अपने डिवाइस के जीवनकाल को बर्बाद नहीं करना चाहते, तब तक लूप में उपयोग न करें ।


8
यह उत्तर अधिक मतों का हकदार है। सवाल का जवाब देना सिर्फ इस जवाब का कारण है।
jagc

"बहुत अधिक पुनरावृत्ति" चेतावनी के बारे में क्या?
ओकी एरी रिनाल्डी

1
@OkiErieRinaldi वहाँ कोई पुनरावृत्ति नहीं है, यह केवल एक लूप है।
रोड्रिगो

7
@ 3.1415926535897932384626433833 ठीक है, किसी ने "नींद" फ़ंक्शन के लिए कहा, यही यहां है। मैंने इसे एक बार इस्तेमाल किया, यह बिल्कुल याद नहीं है कि किस तरह की डिबगिंग है। अगर मुझे कभी भी इसकी आवश्यकता है, तो मुझे पता है कि इसे कहां ढूंढना है। यदि आप किसी अन्य फ़ंक्शन को पसंद करते हैं, तो यह आपकी पसंद है। क्या यह चुनने में सक्षम होने के लिए महान नहीं है?
रोड्रिगो

2
"व्यस्त प्रतीक्षा"।
Zeek2

13

ECMAScript 6 संस्करण, "कोड अवरोधन" के लिए उपज के साथ जनरेटर का उपयोग:

क्योंकि मूल प्रश्न सात साल पहले पोस्ट किया गया था, मैंने सटीक कोड के साथ उत्तर देने की जहमत नहीं उठाई, क्योंकि यह बहुत आसान तरीका है और पहले से ही उत्तर दिया गया है। यदि आप कम से कम दो नींद की जरूरत है, या यदि आप अतुल्यकालिक निष्पादन के लिए योजना बना रहे हैं, तो इसे और अधिक जटिल समस्याओं में मदद करनी चाहिए। अपनी आवश्यकताओं को पूरा करने के लिए इसे संशोधित करने के लिए स्वतंत्र महसूस करें।

let sleeptime = 100
function* clock()
{
    let i = 0
    while( i <= 10000 )
    {
        i++
        console.log(i); // actually, just do stuff you wanna do.
        setTimeout(
            ()=>
            {
                clk.next()
            }
            , sleeptime
        )
        yield
    }
}

let clk = clock()
clk.next()

समारोह*

() => एरो फंक्शन

आप प्रोमिस के माध्यम से भी घटनाओं की श्रृंखला बना सकते हैं :

function sleep(ms)
{
    return(
        new Promise(function(resolve, reject)
        {
            setTimeout(function() { resolve(); }, ms);
        })
    );
}


sleep(1000).then(function()
{
    console.log('1')
    sleep(1000).then(function()
    {
        console.log('2')
    })
})

या बहुत सरल और कम फैंसी तरीका होगा

function sleep(ms, f)
{
    return(
        setTimeout(f, ms)
    )
}


sleep(500, function()
{
    console.log('1')
    sleep(500, function()
    {
        console.log('2')
    })
})
console.log('Event chain launched')

यदि आप कुछ होने की स्थिति का इंतजार कर रहे हैं तो आप इस तरह इंतजार कर सकते हैं

function waitTill(condition, thenDo)
{
    if (eval(condition))
    {
        thenDo()
        return
    }

    setTimeout(
        ()    =>
        {
            waitTill(condition, thenDo)
        }
        ,
        1
    )
}

x=0

waitTill(
    'x>2 || x==1'
    ,
    ()    =>
    {
        console.log("Conditions met!")
    }
)

// Simulating the change
setTimeout(
    () =>
    {
        x = 1
    }
    ,
    1000
)


11

2018 अपडेट

नवीनतम सफ़ारी, फ़ायरफ़ॉक्स और Node.js भी अब async / प्रतीक्षा / वादों का समर्थन कर रहे हैं।

Async / प्रतीक्षा / वादे का उपयोग करना:

(1/2017 के अनुसार, क्रोम पर समर्थित है, लेकिन सफारी, इंटरनेट एक्सप्लोरर, फ़ायरफ़ॉक्स, नोड पर नहीं। Js)

'use strict';

function sleep(ms) {
  return new Promise(res => setTimeout(res, ms));
}

let myAsyncFunc = async function() {
  console.log('Sleeping');
  await sleep(3000);
  console.log('Done');
}

myAsyncFunc();

2017 अपडेट

इस सवाल के पूछे जाने के बाद से जावास्क्रिप्ट विकसित हो गया है और अब इसमें जनरेटर फ़ंक्शन हैं, और नए async / wait / Promise को रोल आउट किया जा रहा है। नीचे दो समाधान हैं, एक जनरेटर फ़ंक्शन के साथ जो सभी आधुनिक ब्राउज़रों पर काम करेगा, और दूसरा, नए async / प्रतीक्षा का उपयोग करके जो अभी तक हर जगह समर्थित नहीं है।

जनरेटर फ़ंक्शन का उपयोग करना:

'use strict';

let myAsync = (g) => (...args) => {
    let f, res = () => f.next(),
        sleep = (ms) => setTimeout(res, ms);
    f = g.apply({sleep}, args); f.next();
};

let myAsyncFunc = myAsync(function*() {
    let {sleep} = this;
    console.log("Sleeping");
    yield sleep(3000);
    console.log("Done");
});

myAsyncFunc();

इस तथ्य पर ध्यान दें कि ये दोनों समाधान प्रकृति में अतुल्यकालिक हैं। इसका मतलब यह है कि माईसिंस्क्यून्क (दोनों मामलों में) सोते समय वापस आ जाएगा।

यह ध्यान रखना महत्वपूर्ण है कि यह प्रश्न नींद के जावास्क्रिप्ट संस्करण () से अलग है? जहां अनुरोधकर्ता कार्रवाई के बीच देरी के बजाय वास्तविक नींद (प्रक्रिया पर कोई अन्य कोड निष्पादन) नहीं मांग रहा है।


1
अब तक का सर्वश्रेष्ठ उत्तर !! मैं हर जगह खोज करने के लिए 30 मिनट बिता चुका हूँ कि .. बड़ा thx !!!
538ROMEO

1
मैं इस जवाब को याद करते हुए एक समाधान ढूंढ रहा था और साइकिल का फिर से आविष्कार किया: D अगर मैं इसे घंटे बचाने से पहले ही देख लेता तो !! Upvoted!
sserzant

let co = gen => (...args) => { let iter = gen(...args); let resume = () => new Promise((resolve, reject) => { let result = iter.next(); if (result.done) resolve(result.value); else Promise.resolve(result.value).then(resume).then(resolve, reject); }); return resume(); };आपको अपने दूसरे कोड ब्लॉक let asyncAdd = co(function* (a, b) { console.log('Sleeping'); yield sleep(3000); console.log('Done'); return a + b; }); asyncAdd(3, 4).then(console.log);की परिभाषा का उपयोग करने देगा sleep()
पैट्रिक रॉबर्ट्स

3

आप कम से कम भद्दा कार्यों चाहते हैं setTimeoutऔर setInterval, आप उन्हें कार्यों में लपेट कर सकते हैं कि सिर्फ बहस के क्रम को उल्टा करने के लिए और उन्हें अच्छा नाम दे:

function after(ms, fn){ setTimeout(fn, ms); }
function every(ms, fn){ setInterval(fn, ms); }

कॉफीस्क्रिप्ट संस्करण:

after = (ms, fn)-> setTimeout fn, ms
every = (ms, fn)-> setInterval fn, ms

फिर आप उन्हें अनाम कार्यों के साथ अच्छी तरह से उपयोग कर सकते हैं:

after(1000, function(){
    console.log("it's been a second");
    after(1000, function(){
        console.log("it's been another second");
    });
});

अब यह आसानी से "एन मिलीसेकंड के बाद, ..." (या "प्रत्येक एन मिलीसेकंड, ...") के रूप में आसानी से पढ़ता है


2

यह करने का एक और तरीका है प्रोमिस और सेटटाइमआउट का उपयोग करके (ध्यान दें कि आपको किसी फ़ंक्शन के अंदर होना चाहिए और इसे एसिंक्रोनस कीवर्ड के साथ एसिंक्रोनस के रूप में सेट करना है):

async yourAsynchronousFunction () {

    var a = 1+3;

    await new Promise( (resolve) => {
        setTimeout( () => { resolve(); }, 3000);
    }

    var b = a + 4;

}

2

यहाँ यह करने के लिए एक बहुत ही सरल तरीका है कि एक तुल्यकालिक नींद / ठहराव की तरह 'महसूस' होता है, लेकिन कानूनी js async कोड है।

// Create a simple pause function
const pause = (timeoutMsec) => new Promise(resolve => setTimeout(resolve,timeoutMsec))

async function main () {
    console.log('starting');
    // Call with await to pause.  Note that the main function is declared asyc
    await pause(3*1000)
    console.log('done');
}


1

आप सादे जावास्क्रिप्ट का उपयोग कर सकते हैं, यह आपके फ़ंक्शन / विधि को 5 सेकंड के बाद कॉल करेगा:

setTimeout(()=> { your_function(); }, 5000);

0

इस समस्या को हल करने के कई तरीके हैं। यदि हम setTimeoutफ़ंक्शन का उपयोग करते हैं, तो आइए इसे पहले जान लें। यह समारोह : तीन पैरामीटर है functionया code, delay(मिलीसेकेंड में) और parameters। चूंकि फ़ंक्शन या कोड पैरामीटर की आवश्यकता है, अन्य वैकल्पिक हैं। एक बार जब आपने देरी से प्रवेश नहीं किया , तो इसे शून्य पर सेट किया जाएगा।

setTimeout() इस लिंक पर जाने के बारे में अधिक जानकारी के लिए

सरलीकृत संस्करण:

var a = 1 + 3;
var b;
console.log('a = ' + a);
setTimeout(function(){ 
    b = a + 4; 
    console.log('b = ' + b);
}, 1000);

आउटपुट:
a = ४
२४ -> सक्रिय टाइमआउट की सूची की संख्या पहचानकर्ता
b = 24


पैरामीटर पास का उपयोग करना:

var a = 1 + 3;
var b;
console.log('a = ' + a);
setTimeout(myFunction, 1000, a);

function myFunction(a)
{
    var b = a + 4;
    console.log('b = ' + b);
}

आउटपुट:
a = ४
२५ -> सक्रिय टाइमआउट की सूची की संख्या पहचानकर्ता
b = 25



ब्राउज़र समर्थन:

क्रोम फ़ायरफ़ॉक्स एज सफारी ओपेरा
1.0 1.0 4.0 1.0 4.0

0

यह मेरा मॉडल है जो दिखाता है कि कैसे एक जनरेटर फ़ंक्शन (ES6) का उपयोग करके जावास्क्रिप्ट में "सो" या "DoEvents" किया जाता है। टिप्पणी कोड:

<html>
<head>
<script>
  "use strict"; // always
  // Based on post by www-0av-Com /programming/3143928
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*
  var divelt, time0, globaln = 0; // global variables
  var MainGenObj = Main(); // generator object = generator function()
window.onload = function() {
  divelt = document.getElementsByTagName("body")[0]; // for addline()
  addline("typeof Main: " + typeof Main);
  addline("typeof MainDriver: " + typeof MainDriver);
  addline("typeof MainGenObj: " + typeof MainGenObj);
  time0 = new Date().valueOf(); // starting time ms
  MainDriver(); // do all parts of Main()
}
function* Main() { // this is "Main" -- generator function -- code goes here
  // could be loops, or inline, like this:

  addline("Part A, time: " + time() + ", " + ++globaln); // part A
  yield 2000;                    // yield for 2000 ms (like sleep)

  addline("Part B, time: " + time() + ", " +  ++globaln); // part B
  yield 3000;                    // yield for 3000 ms (or like DoEvents)

  addline("Part Z, time: " + time() + ", " +  ++globaln); // part Z (last part)
  addline("End, time: " + time());
}
function MainDriver() { // this does all parts, with delays
  var obj = MainGenObj.next(); // executes the next (or first) part of Main()
  if (obj.done == false) { // if "yield"ed, this will be false
    setTimeout(MainDriver, obj.value); // repeat after delay
  }
}
function time() { // seconds from time0 to 3 decimal places
  var ret = ((new Date().valueOf() - time0)/1000).toString();
  if (ret.indexOf(".") == -1) ret += ".000";
  while (ret.indexOf(".") >= ret.length-3) ret += "0";
  return ret;
}
function addline(what) { // output
  divelt.innerHTML += "<br />\n" + what;
}
</script>
</head>
<body>
<button onclick="alert('I\'m alive!');"> Hit me to see if I'm alive </button>
</body>
</html>

0

इस फ़ंक्शन का प्रयास करें:

const delay = (ms, cb) => setTimeout(cb, ms)

यहाँ आप इसका उपयोग कैसे करें:

console.log("Waiting for 5 seconds.")
delay(5000, function() {
  console.log("Finished waiting for 5 seconds.")
})

या वादा करो शैली:

const delay = ms => new Promise(resolve => {
    setTimeout(resolve, ms)
})

यहाँ एक डेमो है

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