2009-11-21 17 views
23

मैंजावास्क्रिप्ट में क्रमशः बराबर टाइमआउट निष्पादित हैं?

setTimeout(foo, 0); 

... 

setTimeout(bar, 0); 

करना मुझे यकीन है कि foo बार से पहले क्रियान्वित करने शुरू हो जाएगा हो सकता है मान लीजिए? क्या होगा यदि 0 के बजाय मैं बार के लिए 1, 10, या 100 का टाइमआउट का उपयोग करता हूं?

सरल प्रयोगों से पता चलता है कि बराबर टाइमआउट मानों के मामले में टाइमआउट लक्ष्य को सेटटाइमआउट के समान क्रम में निष्पादित किया जाता है, लेकिन क्या यह इस व्यवहार पर भरोसा करना सुरक्षित है?

+0

: गारंटी foo के लिए bar आदेश आप कर सकते हैं

var queue = []; function handleQueue() { queue.shift()(); } function queueCallback(callback) { queue.push(callback); setTimeout(handleQueue, 0); } 

अब, , आप इस पृष्ठ पर एक नज़र डालना चाहेंगे http://www.onsip.com/blog/2012/06/29/avoiding-javascript-settimeout-and-setinterval-problems –

उत्तर

4

संक्षेप में, इस पर भरोसा न करें। this पर एक नज़र डालें।

इस आंकड़ा पचाने के लिए जानकारी का एक बहुत कुछ नहीं है, लेकिन यह समझने पूरी तरह से आप कैसे अतुल्यकालिक JavaScript निष्पादन काम करता है की एक बेहतर अहसास दे देंगे।

+7

मुझे उस आलेख में कुछ भी दिखाई नहीं दे रहा है जो सख्ती से बिंदु पर है। सवाल यह नहीं है कि लक्ष्य कार्य निष्पादित किए जाने पर, यह किस क्रम में निष्पादित किया जाता है। – jkl

+1

सख्त आदेश पर भरोसा न करें, यह उपर्युक्त आलेख में "एसिंक्रोनस" का बिंदु है। – jldupont

+4

निश्चित रूप से, वास्तविक देरी अपेक्षा से अधिक हो सकती है, और अंतराल टाइमर की तुलना में अलग-अलग काम करते हैं, लेकिन लेख सीधे प्रश्न का समाधान नहीं करता है। भले ही इसे 'मिली' को निष्पादित करने के लिए 0 मिलीसेकंड या 100 साल लगते हैं, क्या यह हमेशा 'बार' से पहले होगा? या ब्राउज़र मनमाने ढंग से चुन सकता है? मुझे लगता है कि इस पर मानक (या कम से कम कुछ जानकारी) होनी चाहिए। – Calvin

1

निश्चित रूप से देरी वास्तव में हो सकती है, और यह ओएस, ब्राउज़र, ब्राउज़र गतिविधि और कंप्यूटर लोड पर निर्भर करता है। मैं 20ms से नीचे नहीं जाता क्योंकि मुझे लगता है कि इससे कम कुछ भी कोई फर्क नहीं पड़ता है।

जब आप बराबर दो देरी डालते हैं तो इसका मतलब यह नहीं है कि यह उस क्रम में होगा।

आप यह सुनिश्चित करना है कि यह क्रम में किया जाना होगा चाहते हैं मैं इस तरह से कुछ करने के लिए करते हैं:

setTimeout(function() { 
    foo(); 
    setTimeout(bar, 20) 
}, 20); 

यह हमेशा आदेश की गारंटी देगा।

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

+2

क्या आप एक विशिष्ट उदाहरण के बारे में जानते हैं जिसमें ऑर्डर के बराबर टाइमआउट निष्पादित किए जाते हैं? – jkl

+0

मैं इस पर निर्भर करता हूं, जब यह मायने रखता है, क्योंकि मैंने कुछ भी नहीं देखा है जो इसकी गारंटी देता है। –

+1

"सबसे छोटी" उपयोगी देरी कार्यान्वयन और कंप्यूटर की गति पर निर्भर होने जा रही है, लेकिन "0" सेटटाइमआउट के लिए उपयोग करने का एक उपयोगी समय है, क्योंकि यह वर्तमान कॉल स्टैक साफ़ होने तक आमंत्रण को रोकता है। – Nosredna

13

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

विशेष रूप से, किसी दिए गए निष्पादन संदर्भ में आप n के लिए समय समाप्त, और फिर मीटर के लिए एक है, जहां n < = मी, लक्ष्य आदेश समय समाप्ति स्थापित किए गए थे में निष्पादित किया जाएगा निर्धारित करते हैं।

लेकिन इसके लिए मेरा शब्द न लें। मेरा मानना ​​है कि खिड़की का कार्यान्वयन nsGlobalWindow.cpp में है, और यह विधि वास्तव में निर्णय लेती है कि निष्पादन कतार में टाइमआउट कहां जाता है उसे कहा जाता है। ऐसा लगता है कि विधि कतार पीछे की ओर जाता है जो पहले टाइमआउट की तलाश करता है जो दिए गए टाइमआउट से कम या उसके बराबर होता है, और उसके बाद दिए गए टाइमआउट को सम्मिलित करता है।

बेशक जब टाइमआउट सेट किया जाता है तो वर्तमान घड़ी का समय टाइमआउट मान में जोड़ा जाता है। यही कारण है कि अनुक्रम में लक्ष्य को निष्पादित करने के लिए टाइमआउट मानों को nondecreasing क्रम में होना चाहिए।

13

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

आप यहां स्क्रिप्ट को देख/चला सकते हैं: http://jsfiddle.net/se9Jn/ (स्क्रिप्ट क्रॉस-ब्राउज़र संगतता के लिए वाईयूआई का उपयोग करता है, लेकिन वाई। लैटर आंतरिक रूप से सेटटाइमआउट का उपयोग करता है)।

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

आप एक गारंटीकृत आदेश की जरूरत है, मैं पिछले समारोह के अंत में अगले समारोह का समय निर्धारण की सिफारिश करेंगे:

setTimeout(foo, 0); 

... 

function foo() { 

    ... 

    setTimeout(bar, 0); 
} 
3

जवाब है: नहीं, निष्पादन आदेश इसकी गारंटी नहीं है। मैंने कभी-कभी क्रोम 40 में गैर-फीफो ऑर्डरिंग देखी है, खासकर यदि मैं टाइमआउट लंबित होने पर डीबगर में रोकता हूं। मैंने जंगली में भी दुर्लभ नजर डाली थी - यह जांच की गई एक घटना का एकमात्र व्यावहारिक स्पष्टीकरण था।

आप गारंटी निष्पादन आदेश की जरूरत है, setTimeout(callback, 0) के बजाय आप यह कर सकते हैं: आप निष्पादन आदेश के बारे में परवाह है, तो

queueCallback(foo); 
... 
queueCallback(bar);