2009-05-09 28 views
10

मैं सोच रहा था कि जब भी जावा स्क्रिप्ट कोड में समन्वयन करने में एक समाधान मौजूद है। उदाहरण के लिए मेरे पास निम्न मामला है: मैं AJAX कॉल से कुछ प्रतिक्रिया मानों को कैश करने की कोशिश कर रहा हूं, समस्या यह है कि एक साथ कई कॉल करना संभव है, इसलिए यह कोड में दौड़ की स्थिति का कारण बनता है। तो मैं इसके लिए समाधान खोजने के लिए बहुत उत्सुक हूँ? किसी को भी ऐसा विचार है कि करना है?जावास्क्रिप्ट तुल्यकालन विकल्प

उत्तर

4

मुझे मेरी समस्या का समाधान मिला है। मुझे कहना है कि यह उतना सही नहीं है जितना मैं ढूंढ रहा था, लेकिन अब तक यह काम करता है और मैं अस्थायी रूप से काम करने के बारे में सोचता हूं।

$.post("url1", function(data) 
{ 
    // do some computation on data and then 
    setSomeValue(data); 
}); 

var setSomeValue = (function() 
{ 
    var cache = {}; 
    return function(data) 
    { 
     if (cache[data] == "updating") 
     { 
      setTimeout(function(){ setSomeValue(data);}, 100); 
      return; 
     } 
     if (!cache[date]) 
     { 
      cache[date] = updating; 
      $.post("url2", function(another_data) 
      { 
        //make heavy computation on another_data 
        cache[data] = value; 
        // update the UI with value 
      }); 
     } 
     else 
     { 
      //update the UI using cached value 
     } 
    } 
})(); 
+0

इसके लिए धन्यवाद। मुझे आश्चर्य है कि कितने ने कहा "यह एकल धागा है इसलिए यह कोई समस्या नहीं है" जो असीमित कॉलबैक के साथ पूरी दुनिया में गलत है। आपने समस्या को अच्छी तरह से वर्णित किया है और यह मेरे लिए एक बिल्कुल प्रभावी दृष्टिकोण है। –

6

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

+1

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

+1

आपको स्पष्ट रूप से कोड लिखने की आवश्यकता है जो आपके द्वारा वर्णित समस्याओं को संभाल सकता है। थ्रेड को स्मृति से अपूर्ण परिणामों को पढ़ने या बड़े ऑपरेशन के बीच में एक-दूसरे के परिवर्तनों को ओवरराइट करके एक-दूसरे के साथ हस्तक्षेप करने से रोकने के लिए अन्य भाषाओं में आपको सिंक्रनाइज़ेशन की एक ही तरह की आवश्यकता नहीं है। ब्राउज़र वातावरण में जावास्क्रिप्ट निष्पादन की केवल एक सक्रिय स्ट्रीम है। सभी घटना हैंडलरों को एक दूसरे के बाद एक धारावाहिक फैशन में बुलाया जाता है। – fforw

+1

बस उदाहरण के लिए एक AJAX कॉल लिखने का प्रयास करें, फिर हैंडलर में एक और AJAX अनुरोध कॉल करें, और दूसरे हैंडलर में कुछ वैश्विक चर का उपयोग करें। और अब पहली कॉल के कई पुनरावृत्तियों को बनाओ। क्या अभी भी सुनिश्चित है कि उस चर के लिए एक क्रमबद्ध उपयोग है? क्या आप ऑर्डर की भविष्यवाणी कर सकते हैं? और एक और बात अगर मैं समस्या के लिए कामकाजी कोड लिखने में सक्षम था, मैंने वर्णन किया है कि मैं यहां मदद के लिए कभी नहीं पूछूंगा। –

3

हाँ आप गैर IE में अपने XMLHttpRequests तुल्यकालिक कर सकते हैं, खुले पद्धति पर गलत पर asynch option निर्धारित करते हैं, आईई ब्राउज़रों bAsync पैरामीटर के साथ do the same में।

शायद तुम किसी भी तरह आपके अनुरोधों श्रृंखला कर सकते हैं। एक क्यू स्टैक बनाएं और अनुरोध भेजें जब आप क्यू के नीचे अपना रास्ता बनाते हैं।

+1

तुल्यकालिक अनुरोध खराब हैं क्योंकि वे अन्य सभी जावास्क्रिप्ट ईवेंट हैंडलर को निष्पादित होने से रोकते हैं। – fforw

+0

मैंने अभी अपने प्रश्न का उत्तर दिया, मैंने उसकी ज़रूरत का न्याय करने का प्रयास नहीं किया। डाउनवोट कि? हे। –

+0

लोग कई अलग-अलग कारणों से सिंक्रनाइज़ेशन चाहते हैं, उदाहरण के लिए आप किसी और उपयोगकर्ता इनपुट को संभालने से पहले संसाधित होने का अनुरोध चाहते हैं। अन्य कारण भी हैं। आदि –

3

सबसे पहले, यह पता चला है कि सभी मौजूदा जे एस कार्यान्वयन एकल पिरोया हैं महत्वपूर्ण है, इसलिए हम जाति-स्थिति पर चर्चा नहीं कर रहे हैं और संदर्भ यह आम तौर पर प्रयोग किया जाता है में सिंक्रनाइज़ किया जा रहा।

एक तरफ ध्यान दें के रूप में, ब्राउज़रों अब कार्यकर्ता धागे जो जे एस में संगामिति की अनुमति देगा, लेकिन अब यह स्थिति नहीं है शुरू कर रहे हैं।

वैसे भी, आपको अभी भी समस्याएं आ रही हैं कि आप किस डेटा को असीमित कॉल के रूप में प्राप्त करने की उम्मीद कर रहे हैं और आपको कोई गारंटी नहीं है कि आपको चीजें प्राप्त होंगी।

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

+0

ठीक है, मैं अपना मामला सर्वर से कुछ प्रतिक्रियाओं के लिए कैश बनाने की कोशिश कर रहा हूं। एक एजेक्स कॉल है, जिसमें इसका अपना हैंडलर है, लेकिन हैंडलर में फ़ंक्शन के लिए एक कॉल है, जो कैश वैरिएबल तक पहुंचता है और यदि चर सेट किया जाता है तो इसे एक और भारी AJAX कॉल करें। इसलिए यदि मैं एसिंक्रोनस कॉल का उपयोग कर रहा हूं, तो शायद मैं कैश के अपडेट को याद कर सकता हूं और अनावश्यक कॉल दो बार कर सकता हूं, यह व्यवहार अनिच्छुक है, इसलिए मैं उस चर के पढ़ने/लिखने के लिए पहुंच को सिंक्रनाइज़ करने के तरीके के बारे में सोच रहा था। (वर के लिए $ (function() { मैं = 0; मैं some_length <; ++ i) $ .post ("Url", समारोह (डेटा) { setUpSomeValue (डेटा): –

8

मैं एक संभावित समाधान प्रदान कर सकता हूं, लेकिन कोड को देखे बिना ... पूरी तरह से सुनिश्चित नहीं है कि आप क्या कर रहे हैं, लेकिन ऐसा कोई कारण नहीं है कि आप ऐसा क्यों नहीं कर सके।

jQuery में Basic कोड: (परीक्षण नहीं किया और संक्षिप्त ... लेकिन मैं इसी तरह की बातों किया है)

var needAllThese = {}; 

$(function(){ 

     $.ajax("POST","/somepage.aspx",function(data) { 
      needAllThese.A = "VALUE"; 
     }); 

     $.ajax("POST","/somepage2.aspx",function(data) { 
      needAllThese.B = "VALUE"; 
     }); 

     $.ajax("POST","/somepage3.aspx",function(data) { 
      needAllThese.C = "VALUE"; 
     }); 

     startWatching(); 
}); 

function startWatching() { 
    if (!haveEverythingNeeded()) { 
     setTimeout(startWatching,100); 
     return; 
    } 
    everythingIsLoaded(); 
} 

function haveEverythingNeeded() { 
    return needAllThese.A && needAllThese.B && needAllThese.C; 
} 

function everythingIsLoaded() { 
    alert("Everything is loaded!"); 
} 

संपादित करें: (पुन: अपनी टिप्पणी)

आप कॉलबैक के लिए देख रहे हैं, वैसे ही jQuery ऐसा करेगा।

var cache = {}; 

    function getSomeValue(key, callback) { 
     if (cache[key]) callback(cache[key]); 

     $.post("url", function(data) { 
      setSomeValue(key,data); 
      callback(cache[key]); 
     }); 
    } 

    function setSomeValue(key,val) { 
     cache[key] = val; 
    } 

    $(function(){  
     // not sure you would need this, given the code above 
     for (var i = 0; i < some_length; ++i) { 
      $.post("url", function(data){ 
       setSomeValue("somekey",data); 
      }); 
     } 

     getSomeValue("somekey",function(val){    
      $("#element").txt(val);    
     };    
    }); 
+0

कोड इस तरह दिखता है ; }); वर setUpSomeValue = (function() { वर कैश = {} वापसी समारोह (डेटा) { अगर $ .post (.....) (कैश [डेटा]!) // नए डेटा के साथ अपडेट कैश और फिर कैश [डेटा]; } })(); तो जब भी दो समान डेटा मैं वापस आ गया है मैं अभी भी दूसरा AJAX कॉल कर रहा हूं, क्योंकि मैं कैश अपडेट के बारे में सूचित करने में असमर्थ हूं। इसलिए मैं वहां कुछ सिंक्रनाइज़ेशन करने के बारे में सोच रहा हूं। –

+0

ईमानदार होने के लिए मुझे यकीन नहीं है कि मैं समझता हूं कि आखिरी समाधान कैसे मेरी समस्या में मेरी मदद करेगा। क्या आपको थोड़ा समझाने की बात है? –

+0

यह वही करता है जो आपने पूछा था। कॉलबैक का उपयोग करना ... और यदि आपने अपनी टिप्पणी में उदाहरण कोड लिखा है, तो आप अपने $ $ कॉल कॉल में कॉलबैक का उपयोग कर रहे हैं, यह वही अवधारणा है ... जब तक आप कोड नहीं लिखते तब तक आपको इसे समझने में कोई समस्या नहीं होनी चाहिए आपको –

1

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

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

यदि आप तकनीकी प्राप्त करना चाहते हैं तो आप क्यूई के माध्यम से एक विशिष्ट क्यूओएस टाइमआउट सेट कर सकते हैं, फिर से शुरू होने की शुरुआत में स्टॉप घड़ी सेट करें और यदि आप एक विशिष्ट समय तक पहुंचते हैं तो फिर सेट करने के लिए सेटटाइमआउट को कॉल करें पुनरावृत्ति जारी रखने के लिए कतार ... मुझे आशा है कि आपको वह मिल जाएगा :) - यह मूल रूप से सेट की एक्स राशि बचाता है कॉलआउट कॉल केवल एक की आवश्यकता होती है।

उपरोक्त आर्टम बार्गेर्स कोड देखें और आपको जो प्रस्ताव है उसका सारांश प्राप्त करना चाहिए।

संबंधित मुद्दे