उन दोनों में क्या अंतर है, और मैं कब एक का उपयोग करूंगा?
उन दोनों में क्या अंतर है, और मैं कब एक का उपयोग करूंगा?
जवाबों:
सेटटाइमआउट केवल देरी की समाप्ति के बाद फ़ंक्शन को कॉल करने जैसा है। जब भी किसी फ़ंक्शन को कहा जाता है तो उसे तुरंत निष्पादित नहीं किया जाता है, बल्कि कतारबद्ध किया जाता है ताकि इसे सभी निष्पादन के बाद निष्पादित किया जाए और वर्तमान में पंक्तिबद्ध इवेंटहैंडलर पहले समाप्त हों। 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 आपके फाइलसिस्टम कॉल्स में समायोजित हो जाएगा। इसलिए लोड के तहत यह कम प्रदर्शन करेगा। मुझे नहीं लगता कि सेटटाइमआउट बेहतर कर सकता है।
सेटटाइमआउट कुछ समय के बाद कॉलिंग फ़ंक्शंस का अन-इंट्रेक्टिव तरीका है। यह ब्राउज़र में अपनी तरह है। यह सर्वर-साइड के लिए अनुकूल नहीं हो सकता है (यह सोचें कि मैंने बेंचमार्क का उपयोग क्यों किया है। न कि सेटटाइमआउट)।
इवेंट लूप कैसे काम करता है और कुछ गलतफहमी को दूर करता है, इसके बारे में एक शानदार लेख। http://voidcanvas.com/setimmediate-vs-nexttick-vs-settimeout/
लेख का हवाला देते हुए:
setImmediate
कॉलबैक को I / O कतार कॉलबैक समाप्त होने या समय समाप्त होने के बाद कॉल किया जाता है। setImmediate callbacks को चेक क्यू में रखा जाता है, जिसे I / O क्यू के बाद प्रोसेस किया जाता है।
setTimeout(fn, 0)
कॉलबैक को टाइमर कतार में रखा जाता है और I / O कॉलबैक के साथ-साथ चेक कतार कॉलबैक के बाद कॉल किया जाएगा। इवेंट लूप के रूप में, टाइमर क्वीर को प्रत्येक पुनरावृत्ति में पहले प्रोसेस करें, ताकि जिसे पहले निष्पादित किया जाएगा वह इस बात पर निर्भर करता है कि फेज इवेंट लूप कौन सा है।
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);
हमेशा उपयोग करें setImmediate
, जब तक कि आप वास्तव में निश्चित नहीं हैं कि आपको ज़रूरत है setTimeout(,0)
(लेकिन मैं कल्पना भी नहीं कर सकता, इसके लिए क्या)। setImmediate
कॉलबैक को लगभग हमेशा पहले निष्पादित किया जाएगा setTimeout(,0)
, सिवाय इसके कि जब पहली टिक और setImmediate
कॉलबैक में कॉल किया जाए ।
setTimeout
जाने के साथ setImmediate
ही गो- टू होना चाहिए।
आपूर्ति किए गए उत्तरों से पूरी तरह असंतुष्ट। मैंने पोस्ट किया कि मुझे क्या लगता है कि यहां एक बेहतर उत्तर है: https://stackoverflow.com/a/56724489/5992714
प्रश्न मुख्य डुप्लिकेट में उपयोग किए जाने पर सेटटाइमआउट (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);
स्पष्टीकरण यहाँ है
setTimeout (fn, 0) का उपयोग ब्राउज़र को बड़े पैमाने पर अद्यतन में ठंड से रोकने के लिए किया जा सकता है। उदाहरण के लिए websocket.onmessage में, आपके पास HTML परिवर्तन हो सकते हैं, और यदि संदेश आते रहते हैं, तो setImmidiate का उपयोग करते समय ब्राउज़र फ्रीज हो सकता है
उन्हें समझने के लिए कृपया एक बार इवेंट लूप चरणों से गुजरें।
SetImmediate: इसे "चेक" चरण में निष्पादित किया जाता है। जांच चरण आई / ओ चरण के बाद कहा जाता है।
SetTimeOut: इसे "टाइमर" चरण में निष्पादित किया जाता है। टाइमर चरण पहला चरण है लेकिन बाद में कहा जाता है मैं / हे चरण के साथ ही चेक चरण।
निर्धारक तरीके से आउटपुट प्राप्त करने के लिए, यह इस बात पर निर्भर करेगा कि ईवेंट-लूप किस चरण में है; तदनुसार, हम दो में से फ़ंक्शन का उपयोग कर सकते हैं।