NodeJS - setTimeout (fn, 0) बनाम सेटइमाउडेट (fn)


जवाबों:


72

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

setImmediate इस संबंध में समान है सिवाय इसके कि यह फ़ंक्शन की कतार का उपयोग नहीं करता है। यह I / O इवेंटहैंडलर की कतार की जाँच करता है। यदि वर्तमान स्नैपशॉट में सभी I / O ईवेंट संसाधित होते हैं, तो यह कॉलबैक निष्पादित करता है। यह अंतिम I / O हैंडलर के तुरंत बाद उन्हें कतार में ले जाता है, जैसे कि process.nextTick। इसलिए यह तेज है।

इसके अलावा (सेटटाइमआउट, 0) धीमा होगा क्योंकि यह निष्पादन से पहले कम से कम एक बार टाइमर की जांच करेगा। कई बार यह धीमी गति से दोगुना हो सकता है। यहाँ एक बेंचमार्क है।

var Suite = require('benchmark').Suite
var fs = require('fs')

var suite = new Suite

suite.add('deffered.resolve()', function(deferred) {
  deferred.resolve()
}, {defer: true})

suite.add('setImmediate()', function(deferred) {
  setImmediate(function() {
    deferred.resolve()
  })
}, {defer: true})

suite.add('setTimeout(,0)', function(deferred) {
  setTimeout(function() {
    deferred.resolve()
  },0)
}, {defer: true})

suite
.on('cycle', function(event) {
  console.log(String(event.target));
})
.on('complete', function() {
  console.log('Fastest is ' + this.filter('fastest').pluck('name'));
})
.run({async: true})

उत्पादन

deffered.resolve() x 993 ops/sec ±0.67% (22 runs sampled)
setImmediate() x 914 ops/sec ±2.48% (57 runs sampled)
setTimeout(,0) x 445 ops/sec ±2.79% (82 runs sampled)

पहले एक सबसे तेजी से संभव कॉल का विचार देता है। यदि सेटटाइमआउट को अन्य के रूप में कई बार आधा कहा जाता है, तो आप खुद की जांच कर सकते हैं। यह भी याद रखें कि setImmediate आपके फाइलसिस्टम कॉल्स में समायोजित हो जाएगा। इसलिए लोड के तहत यह कम प्रदर्शन करेगा। मुझे नहीं लगता कि सेटटाइमआउट बेहतर कर सकता है।

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


3
यह नोट करना महत्वपूर्ण है कि सेटटाइमआउट कम से कम चार मिलीसेकंड की जबरन देरी के अधीन है यदि पांच बार नेस्टेड हो। देखें html कल्पना
जैक एलन

यह स्रोत (अन्य उत्तर से) यहाँ कुछ कथनों का खंडन करता हुआ प्रतीत होता है: voidcanvas.com/setimmediate-vs-nexttick-vs-settimeout
दिमित्री

17

इवेंट लूप कैसे काम करता है और कुछ गलतफहमी को दूर करता है, इसके बारे में एक शानदार लेख। http://voidcanvas.com/setimmediate-vs-nexttick-vs-settimeout/

लेख का हवाला देते हुए:

setImmediateकॉलबैक को I / O कतार कॉलबैक समाप्त होने या समय समाप्त होने के बाद कॉल किया जाता है। setImmediate callbacks को चेक क्यू में रखा जाता है, जिसे I / O क्यू के बाद प्रोसेस किया जाता है।

setTimeout(fn, 0)कॉलबैक को टाइमर कतार में रखा जाता है और I / O कॉलबैक के साथ-साथ चेक कतार कॉलबैक के बाद कॉल किया जाएगा। इवेंट लूप के रूप में, टाइमर क्वीर को प्रत्येक पुनरावृत्ति में पहले प्रोसेस करें, ताकि जिसे पहले निष्पादित किया जाएगा वह इस बात पर निर्भर करता है कि फेज इवेंट लूप कौन सा है।


I / O कॉलबैक से पहले setTimeout कतार संसाधित की जाती है। ref: nodejs.org/en/docs/guides/event-loop-timers-and-nexttick
मानव

4

setImmediate () I / O ईवेंट्स कॉलबैक के बाद और setTimeout और setInterval से पहले कॉलबैक के तत्काल निष्पादन को शेड्यूल करना है।

setTimeout () देरी मिलीसेकंड के बाद एक बार के कॉलबैक के निष्पादन को निर्धारित करना है।

दस्तावेजों का यही कहना है।

setTimeout(function() {
  console.log('setTimeout')
}, 0)

setImmediate(function() {
  console.log('setImmediate')
})

यदि आप उपरोक्त कोड चलाते हैं, तो परिणाम इस तरह होगा ... भले ही वर्तमान दस्तावेज़ में कहा गया है कि "I / O ईवेंट्स कॉलबैक के बाद और सेटटाइमआउट और सेटइंटरवल से पहले कॉलबैक को" तत्काल "निष्पादित करने के लिए।" ..

परिणाम..

setTimeout

setImmediate

यदि आप अपने उदाहरण को दूसरे टाइमर में लपेटते हैं, तो यह हमेशा सेट प्रिंट करता है और उसके बाद सेटटाइमआउट होता है।

setTimeout(function() {
  setTimeout(function() {
    console.log('setTimeout')
  }, 0);
  setImmediate(function() {
    console.log('setImmediate')
  });
}, 10);

तो आप कब एक को पसंद करेंगे?
श्लोमी श्वार्ट्ज

23
आपने यह नहीं बताया कि आपने जो दिखाया वह क्यों होता है। यह उत्तर मेरे लिए उपयोगी नहीं था।
क्लिंट ईस्टवुड

3
@Savannah आपके पहले परिणाम में, कृपया बताएं कि क्यों setTimeout setImmediate से पहले पहले मार डाला
Agus Syahputra


1
सभी समय पर सेट टाइमआउट और सेट इन्टरवल से पहले SetImmediate wont execute
Midhun GS

2

हमेशा उपयोग करें setImmediate, जब तक कि आप वास्तव में निश्चित नहीं हैं कि आपको ज़रूरत है setTimeout(,0)(लेकिन मैं कल्पना भी नहीं कर सकता, इसके लिए क्या)। setImmediateकॉलबैक को लगभग हमेशा पहले निष्पादित किया जाएगा setTimeout(,0), सिवाय इसके कि जब पहली टिक और setImmediateकॉलबैक में कॉल किया जाए ।


1
मैं कहूंगा कि setImmediate के बजाय setTimeout का उपयोग करने का मुख्य कारण यह है कि आपके कोड को उन ब्राउज़रों द्वारा निष्पादित करने की आवश्यकता है जिनके पास setImmediate लागू नहीं है। फिर भी, आप केवल एक शिम बना सकते हैं।
19ory में ग्रेगरी मगशर्क

9
यह बिना सोचे-समझे सलाह है। यदि सब कुछ पहले जाने के लिए कहता है, तो अतुल्यकालिक निष्पादन की आकस्मिक प्रदर्शन विशेषताएं अंत में कतार-आईएनजी की तुलना में कबाड़ होने वाली हैं। आवश्यक होने पर ही उपयोग किए setTimeoutजाने के साथ setImmediateही गो- टू होना चाहिए।
अमीर रिमेर

1

आपूर्ति किए गए उत्तरों से पूरी तरह असंतुष्ट। मैंने पोस्ट किया कि मुझे क्या लगता है कि यहां एक बेहतर उत्तर है: https://stackoverflow.com/a/56724489/5992714

प्रश्न मुख्य डुप्लिकेट में उपयोग किए जाने पर सेटटाइमआउट (0) और सेटमीडिएट () के अपरिभाषित होने का संभावित डुप्लिकेट क्यों है?


1
कृपया दो प्रश्नों के समान उत्तर न दें। यदि प्रश्न अलग-अलग हैं, तो प्रत्येक को उत्तर दर्जी दें। यदि वे समान हैं, तो ध्वज या वोट को डुप्लिकेट के रूप में बंद करने के लिए।
टॉम ज़िक

@ टॉम्झिक ने नोट किया।
मानव

0

मुझे लगता है कि नव्या एस का उत्तर सही नहीं है, यहां मेरा परीक्षण कोड है:

let set = new Set();

function orderTest() {
  let seq = [];
  let add = () => set.add(seq.join());
  setTimeout(function () {
    setTimeout(function () {
      seq.push('setTimeout');
      if (seq.length === 2) add();
    }, 0);

    setImmediate(function () {
      seq.push('setImmediate');
      if (seq.length === 2) add();
    });
  }, 10);
}

// loop 100 times
for (let i = 0; i < 100; i++) {
  orderTest();
}

setTimeout(() => {
  // will print one or two items, it's random
  for (item of set) {
    console.log(item);
  }
}, 100);

स्पष्टीकरण यहाँ है


0

setTimeout (fn, 0) का उपयोग ब्राउज़र को बड़े पैमाने पर अद्यतन में ठंड से रोकने के लिए किया जा सकता है। उदाहरण के लिए websocket.onmessage में, आपके पास HTML परिवर्तन हो सकते हैं, और यदि संदेश आते रहते हैं, तो setImmidiate का उपयोग करते समय ब्राउज़र फ्रीज हो सकता है


0

उन्हें समझने के लिए कृपया एक बार इवेंट लूप चरणों से गुजरें।

SetImmediate: इसे "चेक" चरण में निष्पादित किया जाता है। जांच चरण आई / ओ चरण के बाद कहा जाता है।

SetTimeOut: इसे "टाइमर" चरण में निष्पादित किया जाता है। टाइमर चरण पहला चरण है लेकिन बाद में कहा जाता है मैं / हे चरण के साथ ही चेक चरण।

निर्धारक तरीके से आउटपुट प्राप्त करने के लिए, यह इस बात पर निर्भर करेगा कि ईवेंट-लूप किस चरण में है; तदनुसार, हम दो में से फ़ंक्शन का उपयोग कर सकते हैं।


-5

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

नियंत्रित देरी के लिए setTimeout () का उपयोग करें। निर्दिष्ट देरी के बाद फ़ंक्शन चलेगा। न्यूनतम देरी 1 मिलीसेकंड है।

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