एम्बर रनअप क्या है और यह कैसे काम करता है?


96

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

  • एम्बर रनलूप कब शुरू होता है। क्या यह राउटर या व्यूज या कंट्रोलर्स या किसी और चीज पर निर्भर है?
  • लगभग कितना समय लगता है (मुझे पता है कि यह पूछने के लिए मूर्खतापूर्ण है और कई चीजों पर निर्भर है लेकिन मैं एक सामान्य विचार की तलाश कर रहा हूं, या हो सकता है कि अगर कोई न्यूनतम या अधिकतम समय एक रनअप ले सकता है)
  • क्या रनऑलॉप को हर समय निष्पादित किया जा रहा है, या यह केवल निष्पादन की शुरुआत से अंत तक की अवधि का संकेत दे रहा है और कुछ समय के लिए नहीं चल सकता है।
  • यदि एक रनऑलॉप से ​​एक दृश्य बनाया जाता है, तो क्या यह गारंटी है कि लूप के समाप्त होने तक इसकी सभी सामग्री इसे DOM में बना देगी?

मुझे माफ़ कर देना अगर ये बहुत बुनियादी सवाल हैं, तो मुझे लगता है कि इनको समझने से मेरे जैसे एम्बर को बेहतर तरीके से इस्तेमाल करने में मदद मिलेगी।


5
रन लूप के बारे में महान डॉक्स नहीं हैं। मैं इस सप्ताह एक छोटी स्लाइड डेक को एक साथ रखने की कोशिश करने जा रहा हूं।
ल्यूक मेलिया

2
@ ल्यूकमेलिया इस सवाल पर अभी भी आपके ध्यान की सख्त जरूरत है और ऐसा लगता है कि कुछ अन्य लोग भी इसी जानकारी की तलाश में हैं। यदि आपके पास एक मौका है, तो रनऑलॉप के बारे में अपनी अंतर्दृष्टि साझा करना अद्भुत होगा।
अरस

जवाबों:


199

अपडेट 10/9/2013: रन लूप के इस इंटरैक्टिव विज़ुअलाइज़ेशन की जाँच करें: https://machty.s3.amazonaws.com/ember-run-loop-visual/index.html

अद्यतन 5/9/2013: नीचे दी गई सभी बुनियादी अवधारणाएँ अभी भी अद्यतित हैं, लेकिन इस प्रतिबद्ध के अनुसार , एम्बर रन लूप कार्यान्वयन को एक अलग पुस्तकालय में विभाजित किया गया है जिसे बैकबर्नर.जेएस कहा जाता है , जिसमें कुछ बहुत ही मामूली एपीआई अंतर हैं।

सबसे पहले, इन्हें पढ़ें:

http://blog.sproutcore.com/the-run-loop-part-1/

http://blog.sproutcore.com/the-run-loop-part-2/

वे एम्बर से 100% सटीक नहीं हैं, लेकिन रनऑलॉप के पीछे मुख्य अवधारणाएं और प्रेरणा अभी भी आम तौर पर एम्बर पर लागू होती हैं; केवल कुछ कार्यान्वयन विवरण अलग हैं। लेकिन, आपके सवालों पर:

एम्बर रनलूप कब शुरू होता है। क्या यह राउटर या व्यूज या कंट्रोलर्स या किसी और चीज पर निर्भर है?

सभी मूल उपयोगकर्ता ईवेंट (जैसे कीबोर्ड ईवेंट, माउस ईवेंट, आदि) रन लूप को आग देंगे। यह गारंटी देता है कि कैप्चर किए गए (माउस / कीबोर्ड / टाइमर / आदि) इवेंट द्वारा बाध्य गुणों के लिए जो भी परिवर्तन किए गए हैं, वे सिस्टम पर नियंत्रण वापस करने से पहले एम्बर के डेटा-बाइंडिंग सिस्टम में पूरी तरह से प्रचारित हैं। तो, अपने माउस को ले जाना, एक कुंजी दबाकर, एक बटन क्लिक करना आदि, सभी रन लूप लॉन्च करते हैं।

लगभग कितना समय लगता है (मुझे पता है कि यह पूछने के लिए मूर्खतापूर्ण है और कई चीजों पर निर्भर है लेकिन मैं एक सामान्य विचार की तलाश कर रहा हूं, या हो सकता है कि अगर कोई न्यूनतम या अधिकतम समय एक रनअप ले सकता है)

किसी भी बिंदु पर RunLoop कभी भी ट्रैक नहीं रखेगा कि सिस्टम के माध्यम से सभी परिवर्तनों को प्रचारित करने में कितना समय लग रहा है और फिर अधिकतम समय सीमा तक पहुंचने के बाद RunLoop को रोक दें; इसके बजाय, RunLoop हमेशा पूरा करने के लिए चलेगा, और तब तक नहीं रुकेगा जब तक कि सभी समयसीमा समाप्त नहीं हो गई है, बाइंडिंग प्रचारित किया गया है, और शायद उनके बाइंडिंग ने प्रचार किया, और इसी तरह। जाहिर है, जितने अधिक परिवर्तन एक ही घटना से प्रचारित करने की जरूरत है, रनऑलॉप को खत्म करने में उतना ही अधिक समय लगेगा। यहां एक और (बहुत अनुचित) उदाहरण दिया गया है कि कैसे रनऑलॉप एक अन्य ढांचे (बैकबोन) की तुलना में प्रचार परिवर्तनों से टकरा सकता है जिसमें एक रन लूप नहीं है: http://jsfiddle.net/jashkenas/CGSd5/। मोरल ऑफ़ द स्टोरी: रनऑलॉप का वास्तव में सबसे तेज़ चीज़ों के लिए तेज़ जो आप कभी एम्बर में करना चाहते हैं, और यह वह जगह है जहाँ एम्बर की बहुत शक्ति निहित है, लेकिन यदि आप स्वयं को 60 फ्रेम प्रति सेकंड पर जावास्क्रिप्ट के साथ 30 सर्कल को चेतन करना चाहते हैं, तो एम्बर के रनऑलॉप पर भरोसा करने की तुलना में इसके बारे में बेहतर तरीके हो सकते हैं।

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

इसे हर समय निष्पादित नहीं किया जाता है - इसे किसी बिंदु पर सिस्टम पर वापस नियंत्रण वापस करना पड़ता है या फिर आपका ऐप लटका रहता है - यह अलग है, कहते हैं, एक सर्वर पर एक रन लूप है जो एक है while(true)और अनंत तक चलता है सर्वर को बंद करने के लिए एक संकेत मिलता है ... एम्बर रनऑलॉप में ऐसा while(true)नहीं है, लेकिन उपयोगकर्ता / टाइमर घटनाओं के जवाब में केवल काता जाता है।

यदि एक रनऑलॉप से ​​एक दृश्य बनाया जाता है, तो क्या यह गारंटी है कि लूप के समाप्त होने तक इसकी सभी सामग्री इसे DOM में बना देगी?

देखते हैं कि क्या हम इसका पता लगा सकते हैं। SC से Ember RunLoop में बड़े बदलावों में से एक यह है कि, स्प्राउटकोर RL के बारे में पहले लिंक में invokeOnceऔर invokeLast(जो आप आरेख में देखते हैं) के बजाय, Ember आपको 'कतारों' की एक सूची प्रदान करता है, रन लूप का कोर्स, आप क्रियाओं (रन लूप के दौरान बुलाया जाने वाला कार्य) को निर्दिष्ट करके बता सकते हैं कि क्रिया किस कतार में है (स्रोत से उदाहरण:) Ember.run.scheduleOnce('render', bindView, 'rerender');

यदि आप run_loop.jsस्रोत कोड को देखते हैं Ember.run.queues = ['sync', 'actions', 'destroy', 'timers'];, तो आप देखते हैं , फिर भी यदि आप एक एम्बर ऐप में ब्राउज़र में अपना जावास्क्रिप्ट डीबगर खोलते हैं और मूल्यांकन करते हैं Ember.run.queues, तो आपको कतारों की एक पूरी सूची मिलती है ["sync", "actions", "render", "afterRender", "destroy", "timers"]:। एम्बर अपने कोडबेस को बहुत मॉड्यूलर रखता है, और वे आपके कोड के साथ-साथ लाइब्रेरी के एक अलग हिस्से में अपने कोड को और अधिक कतारें डालने के लिए संभव बनाते हैं। इस मामले में, एम्बर व्यू लाइब्रेरी आवेषण renderऔर afterRenderकतार, विशेष रूप से actionsकतार के बाद । मैं एक सेकंड में क्यों हो सकता है। सबसे पहले, RunLoop एल्गोरिथ्म:

RunLoop एल्गोरिथ्म बहुत समान है जैसा कि SC रन लूप लेख में वर्णित है:

  • आप अपना कोड RunLoop के बीच चलाते हैं .begin()और .end(), केवल Ember में आप अपना कोड चलाना चाहते हैं Ember.run, जो आंतरिक रूप से beginऔर आपके endलिए कॉल करेगा । (एम्बर कोड आधार में केवल आंतरिक रन लूप कोड अभी भी उपयोग करता है beginऔर end, इसलिए आपको बस साथ रहना चाहिए Ember.run)
  • बाद end()कहा जाता है, RunLoop तो गियर में kicks हर एक के लिए पारित कोड का हिस्सा द्वारा किए गए परिवर्तन लागू होने Ember.runकार्य करते हैं। इसमें बाध्य गुणों के मूल्यों का प्रचार करना, DOM के लिए दृश्य परिवर्तन प्रदान करना, इत्यादि शामिल हैं। इन कार्यों (बाध्यकारी, DOM तत्वों आदि का प्रतिपादन) के क्रम को Ember.run.queuesऊपर वर्णित सरणी द्वारा निर्धारित किया जाता है:
  • रन लूप पहली कतार पर शुरू होगा, जो है sync। यह उन सभी कार्यों को चलाएगा syncजो Ember.runकोड द्वारा कतार में निर्धारित किए गए थे । ये क्रियाएं स्वयं भी इसी RunLoop के दौरान किए जाने वाले अधिक कार्यों को शेड्यूल कर सकती हैं, और यह सुनिश्चित करने के लिए RunLoop पर निर्भर है कि यह प्रत्येक क्रिया को तब तक करता है जब तक कि सभी कतार फ़्लश न हो जाएं। जिस तरह से यह होता है, वह प्रत्येक कतार के अंत में, RunLoop पहले की सभी निस्तब्ध कतारों को देखेगा और देखेगा कि क्या कोई नया कार्य निर्धारित किया गया है। यदि ऐसा है, तो इसे बिना किसी निर्धारित क्रिया के जल्द से जल्द कतार की शुरुआत में शुरू करना होगा और कतार से बाहर निकलना होगा, अपने कदमों का पता लगाना जारी रखना चाहिए और जब तक आवश्यक न हो तब तक शुरू करें जब तक कि सभी कतारें पूरी तरह से खाली न हो जाएं।

यही एल्गोरिथ्म का सार है। इस प्रकार ऐप के माध्यम से बाध्य डेटा का प्रचार होता है। आप उम्मीद कर सकते हैं कि एक रनऑलॉप पूरा होने के बाद, सभी बाउंड डेटा को पूरी तरह से प्रचारित किया जाएगा। तो, डोम तत्वों के बारे में क्या?

एम्बर व्यू लाइब्रेरी द्वारा जोड़े गए कतारों का क्रम यहाँ महत्वपूर्ण है। उस पर ध्यान दें renderऔर afterRenderउसके बाद sync, और actionsyncकतार बाध्य डेटा प्रचार के लिए सभी कार्यों में शामिल है। ( action, उसके बाद, केवल एम्बर स्रोत में ही उपयोग किया जाता है)। उपरोक्त एल्गोरिथ्म के आधार पर, यह गारंटी दी जाती है कि जब तक RunLoop renderकतार में पहुंचता है , तब तक डेटा-बाइंडिंग के सभी सिंक्रनाइज़ेशन समाप्त हो जाएंगे। यह डिज़ाइन द्वारा है: आप पहले DOM तत्वों को रेंडर करने का महंगा काम नहीं करना चाहेंगेडेटा-बाइंडिंग को सिंक करना, क्योंकि इसके बाद अपडेट किए गए डेटा के साथ DOM तत्वों को फिर से प्रस्तुत करना होगा - जाहिर है कि सभी RunLoop कतारों को खाली करने का एक बहुत ही अक्षम और त्रुटि-युक्त तरीका। तो एम्बर समझदारी से सभी डेटा-बाइंडिंग कार्य के माध्यम से विस्फोट करता है जो कि renderक्यू में डोम तत्वों को रेंडर करने से पहले कर सकता है ।

तो, अंत में, अपने प्रश्न का उत्तर देने के लिए, हाँ, आप उम्मीद कर सकते हैं कि किसी भी आवश्यक DOM रेंडरिंग ने समय Ember.runसमाप्त हो गया है। यहाँ एक jsField प्रदर्शित करने के लिए है: http://jsfiddle.net/machty/6p6XJ/328/

RunLoop के बारे में जानने के लिए अन्य बातें

पर्यवेक्षकों बनाम बाइंडिंग

यह ध्यान रखना महत्वपूर्ण है कि ऑब्जर्वर और बाइंडिंग, एक "देखे गए" संपत्ति में परिवर्तनों के जवाब की समान कार्यक्षमता होने के बावजूद, एक RunLoop के संदर्भ में पूरी तरह से अलग व्यवहार करते हैं। बाइंडिंग प्रचार, जैसा कि हमने देखा है, syncअंततः रनऑलॉप द्वारा निष्पादित करने के लिए कतार में शेड्यूल किया जाता है । दूसरी ओर, पर्यवेक्षकों ने तुरंत देखा कि जब देखी गई संपत्ति पहले बिना रनऑलॉप कतार में निर्धारित किए बिना बदल जाती है। यदि एक पर्यवेक्षक और एक ही संपत्ति के सभी "वॉच" को एक बाध्यकारी करता है, तो पर्यवेक्षक को हमेशा उस समय से 100% कहा जाएगा जब बाध्यकारी से पहले अद्यतन किया जाएगा।

scheduleOnce तथा Ember.run.once

एम्बर के ऑटो-अपडेटिंग टेम्प्लेट में से एक बड़ी दक्षता को बढ़ावा देता है, इस तथ्य पर आधारित है कि, रनऑलॉप के लिए धन्यवाद, एक समान कार्रवाई में कई समान रनऑलॉप क्रियाओं को coalesced ("बहस" किया जा सकता है, यदि आप करेंगे)। आप इस पर गौर करते हैं run_loop.jsinternals, आप कार्यों कि इस व्यवहार को सुविधाजनक बनाने के संबंधित कार्य हैं देखेंगे scheduleOnceऔर Em.run.once। उनके बीच का अंतर इतना महत्वपूर्ण नहीं है क्योंकि वे जानते हैं कि वे मौजूद हैं, और वे रन लूप के दौरान बहुत से फूला हुआ, बेकार गणना को रोकने के लिए कतार में डुप्लिकेट कार्यों को कैसे छोड़ सकते हैं।

टाइमर के बारे में क्या?

भले ही 'टाइमर' ऊपर सूचीबद्ध डिफ़ॉल्ट कतारों में से एक है, लेकिन एम्बर केवल उनके रनअप टेस्ट मामलों में कतार का संदर्भ देता है। ऐसा लगता है कि इस तरह की कतार का इस्तेमाल स्प्राउटकोर दिनों में किया गया होगा जो उपरोक्त लेखों में से कुछ विवरणों के आधार पर टाइमर के बारे में आग लगाने की अंतिम बात है। एम्बर में, timersकतार का उपयोग नहीं किया जाता है। इसके बजाय, RunLoop को आंतरिक रूप से प्रबंधित setTimeoutईवेंट ( invokeLaterTimersफ़ंक्शन देखें ) द्वारा काटा जा सकता है , जो कि सभी मौजूदा टाइमर के माध्यम से लूप करने के लिए पर्याप्त बुद्धिमान है, जो सभी समाप्त हो गए हैं उन्हें आग दें, भविष्य के टाइमर को निर्धारित करें, और एक आंतरिक सेट करेंsetTimeoutकेवल उस घटना के लिए, जो आग लगने पर रनऑलॉप को फिर से स्पिन करेगी। प्रत्येक टाइमर कॉल सेटटाइमआउट और खुद को जगाने की तुलना में यह दृष्टिकोण अधिक कुशल है, क्योंकि इस मामले में, केवल एक सेटटाइमआउट कॉल करने की आवश्यकता है, और रनऑलॉप सभी अलग-अलग टाइमर को आग लगाने के लिए पर्याप्त स्मार्ट है जो एक ही समय में बंद हो सकते हैं। समय।

syncकतार के साथ आगे की बहस

यहां रन लूप से एक स्निपेट है, रन लूप में सभी कतारों के माध्यम से लूप के बीच में। syncकतार के लिए विशेष मामले पर ध्यान दें : क्योंकि syncएक विशेष रूप से अस्थिर कतार है, जिसमें डेटा को हर दिशा में प्रचारित किया जा रहा है, Ember.beginPropertyChanges()किसी भी पर्यवेक्षकों को गोली चलाने से रोकने के लिए कहा जाता है, इसके बाद कॉल किया जाता है Ember.endPropertyChanges। यह समझदारी है: यदि syncकतार को फ्लश करने के दौरान , यह पूरी तरह से संभव है कि किसी वस्तु पर एक संपत्ति अपने अंतिम मूल्य पर आराम करने से पहले कई बार बदल जाएगी, और आप हर एक बदलाव के दौरान पर्यवेक्षकों को तुरंत फायरिंग करके संसाधनों को बर्बाद नहीं करना चाहेंगे। ।

if (queueName === 'sync') 
{
    log = Ember.LOG_BINDINGS;

    if (log) 
    {
        Ember.Logger.log('Begin: Flush Sync Queue');
    }

    Ember.beginPropertyChanges();
    Ember.tryFinally(tryable, Ember.endPropertyChanges);

    if (log) 
    { 
        Ember.Logger.log('End: Flush Sync Queue'); 
    }
} 
else 
{
   forEach.call(queue, iter);
}

उम्मीद है की यह मदद करेगा। मुझे निश्चित रूप से इस बात को लिखने के लिए काफी कुछ सीखना था, जो इस तरह का था।


3
महान राइटअप! मैं अफवाहें सुनता हूं कि "पर्यवेक्षक तुरंत आग लगाते हैं" बात कुछ बिंदु पर बदल सकती है, जिससे उन्हें बाइंडिंग की तरह देरी हो सकती है।
जो लेइस

@JoLiss हाँ, मुझे लगता है कि मैंने कुछ महीनों के बारे में सुना है ... निश्चित नहीं है कि कब / जब यह इसे
बनाएगा

1
ब्रेंडन ब्रिग्स ने जनवरी 2014 के Ember.js NYC मीटअप में रन लूप के बारे में शानदार प्रस्तुति दी। यहाँ वीडियो: youtube.com/watch?v=iCZUKFNXA0k
ल्यूक मेलिया

1
यह उत्तर सबसे अच्छा संसाधन था जो मैंने एम्बर रन लूप के बारे में पाया, बहुत अच्छा काम! मैंने हाल ही में आपके काम के आधार पर रन लूप के बारे में एक व्यापक ट्यूटोरियल प्रकाशित किया है जो मुझे उम्मीद है कि उस तंत्र के और भी अधिक विवरणों का वर्णन करता है। यहाँ पर उपलब्ध है। www.guru.co/ember-ebook-form
Kuba Niechciał
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.