2011-07-26 23 views
40

यह मूर्खतापूर्ण प्रतीत होता है, लेकिन मुझे यह नहीं पता कि jQuery के साथ एसिंक्रोनस फ़ंक्शन कॉल कैसे करें जिसमें कुछ सर्वर-साइड अनुरोध शामिल नहीं है। मेरे पास धीमा कार्य है जो बहुत से डोम तत्वों के माध्यम से पुनरावृत्त करता है, और मैं चाहता हूं कि यह कार्य चल रहा है, जबकि ब्राउज़र चालू नहीं हो रहा है। धीमे फ़ंक्शन को कॉल करने से पहले मैं थोड़ा संकेतक प्रदर्शित करना चाहता हूं, फिर जब धीमा फ़ंक्शन वापस आता है, तो मैं सूचक को छिपाना चाहता हूं। मैं निम्नलिखित है:jQuery एसिंक्रोनस फ़ंक्शन कॉल, कोई AJAX अनुरोध

$('form#filter', parentNode).submit(function() { 
    var form = $(this); 
    indicator.show(); 
    var textField = $('input#query', form); 
    var query = jQuery.trim(textField.val()); 
    var re = new RegExp(query, "i"); 
    slowFunctionCall(); // want this to happen asynchronously; all client-side 
    indicator.hide(); 
    return false; 
}); 

वर्तमान में मैं पत्र भरना होगा और संकेतक प्रदर्शित नहीं किया जाता है, ब्राउज़र जम जाता है, और फिर slowFunctionCall समाप्त हो गया है।

संपादित करें: मैं Vivin's answer विशेष रूप से Sitepoint link इस्तेमाल किया है, तो निम्न समाधान पाने के लिए:

var indicator = $('#tagFilter_loading', parentNode); 
indicator.hide(); 
var spans = $('div#filterResults span', parentNode); 
var textField = $('input#query', parentNode); 
var timer = undefined, processor = undefined; 
var i=0, limit=spans.length, busy=false; 
var filterTags = function() { 
    i = 0; 
    if (processor) { 
    clearInterval(processor); 
    } 
    indicator.show(); 
    processor = setInterval(function() { 
    if (!busy) { 
     busy = true; 
     var query = jQuery.trim(textField.val()).toLowerCase(); 
     var span = $(spans[i]); 
     if ('' == query) { 
     span.show(); 
     } else { 
     var tagName = span.attr('rel').toLowerCase(); 
     if (tagName.indexOf(query) == -1) { 
      span.hide(); 
     } 
     } 
     if (++i >= limit) { 
     clearInterval(processor); 
     indicator.hide(); 
     } 
     busy = false; 
    } 
    }, 1); 
}; 
textField.keyup(function() { 
    if (timer) { 
    clearTimeout(timer); 
    } 
    /* Only start filtering after the user has finished typing */ 
    timer = setTimeout(filterTags, 2000); 
}); 
textField.blur(filterTags); 

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

+0

मुझे लगता है कि सभी जेएस एक ही धागे में चलता है। तो अतुल्यकालिक कार्यों को चलाने के लिए संभव नहीं है। लेकिन मैं इसके बारे में गलत हो सकता हूं :) – PeeHaa

+1

इस बात पर निर्भर करते हुए कि आप अपने कार्य को धीमा कर रहे डीओएम तत्वों को कैसे एक्सेस कर रहे हैं, आप इस भाग को तेज़ी से बढ़ा सकते हैं। क्या आप वर्ग या विशेषता फ़िल्टर (धीमी) का उपयोग कर JQuery के तत्वों तक पहुंच रहे हैं? क्या फ़ंक्शन एक से अधिक बार चलता है और क्या कोई तरीका है कि आप उन तत्वों/आईडी को कैश कर सकते हैं जिनके साथ आप बातचीत कर रहे हैं? क्या आप एक सीएसएस वर्ग को बदलकर एक ही डोम अपडेट कर सकते हैं जो सभी प्रभावित तत्वों का उपयोग करते हैं? – tomfumb

उत्तर

30

जावास्क्रिप्ट एक ही धागे में चलता है और इसलिए यदि आपके पास धीमा कार्य है तो अन्य सभी को अवरुद्ध कर देगा।

अद्यतन

कि आप क्या चाहते हैं में से कुछ भी करेंगे, लेकिन वे हैं कि ध्यान में रखना व्यापक रूप से समर्थित IE में समर्थित (मुझे लगता है कि वे IE10 में हो जाएगा) नहीं।

वेब कर्मचारी पर कुछ संसाधन:

यहाँ वेब श्रमिकों के बिना बहु सूत्रण को पूरा करने पर कुछ संसाधन हैं। यह ध्यान रखें कि यह "सही" बहु सूत्रण नहीं है महत्वपूर्ण है:

+0

अच्छा, कोई आश्चर्य नहीं कि मुझे इसके बारे में कुछ ट्यूटोरियल नहीं मिल रहा है ... धन्यवाद। –

+0

आप महोदय, अतीत में सही रहे होंगे, अब कुछ ब्राउज़र वेब श्रमिकों का समर्थन करते हैं। – nwellcome

+1

@ स्वागत है मैंने इसका भी उल्लेख किया है, लेकिन यह इस तथ्य के कारण एक व्यवहार्य विकल्प नहीं है कि यह व्यापक रूप से समर्थित नहीं है। मुझे उम्मीद है कि आखिरकार वे व्यापक रूप से समर्थित होंगे, क्योंकि यह बहुत उपयोगी होगा। –

6

मैं जा रहा था एक टाइमआउट को देखने का सुझाव देने के लिए लेकिन हां। जॉन रेसिग (jQuery का) द्वारा यह पोस्ट इस बारे में कुछ बताता है कि जावास्क्रिप्ट अपने एकल धागे को कैसे संभालता है। http://ejohn.org/blog/how-javascript-timers-work/

This article भी बताते हैं: "जब जावास्क्रिप्ट में अतुल्यकालिक रूप से कार्यों को क्रियान्वित करने से एक बात को याद है, पेज में अन्य सभी JavaScript निष्पादन रुकती एक समारोह कॉल के पूर्ण होने तक है यह सब कैसे मौजूदा ब्राउज़र JavaScript निष्पादित, और पैदा कर सकता है। असली प्रदर्शन समस्याएं यदि आप एक ही समय में असीमित रूप से बहुत सी चीजों को कॉल करने का प्रयास कर रहे हैं। एक लंबे समय तक चलने वाला फ़ंक्शन वास्तव में उपयोगकर्ता के लिए ब्राउज़र को "लॉक" करेगा।एक ही तुल्यकालिक समारोह भी कॉल के लिए सच है। "

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

उदाहरण के लिए इस समारोह:

// Sync 
(function() { 
    for(var x = 0; x < 100000; ++x) {console.log(x)} 
})() 

// ASync 
var x = 0; 
setTimeout(function() { 
    console.log(x++); 
    if(x < 100000) setTimeout(arguments.callee, 1); 
} ,1) 
+0

यदि आप arguments.callee का उपयोग नहीं करना चाहते हैं (यह ईएस 5 के बाद सख्त मोड में वर्जित है), तो आप कॉलबैक फ़ंक्शन को एक नाम दे सकते हैं और अगली कॉल में इसका नाम उपयोग कर सकते हैं। उदाहरण के लिए: var x = 0; सेटटाइमआउट (फ़ंक्शन रिक() { console.log (x ++); यदि (x <100000) setTimeout (rec, 1); }, 1) – danpop

5

आप चाहते हो सकता है web workers!

संपादित करें: कितने लोगों को "अपने संभव नहीं" करने के लिए कूद गया मैं हैरान हूँ तो मैं विस्तृत करेंगे। वेब श्रमिक HTML 5 spec का हिस्सा हैं। वे यूआई को अवरुद्ध किए बिना पृष्ठभूमि में स्क्रिप्ट चलाने के लिए धागे को फैलाने की अनुमति देते हैं। वे बाहरी जेएस फाइलें होनी चाहिए,

var worker = new Worker('my_task.js'); 

द्वारा आवंटित की जाती हैं और घटनाओं के माध्यम से संवाद की जाती हैं।

+0

कुछ हो सकता है। वह पृष्ठ कहता है, "सामान्य रूप से, पृष्ठभूमि धागे-श्रमिकों सहित- डीओएम में हेरफेर नहीं कर सकता"। –

+0

गूड प्वाइंट, कर्मचारी 'विंडो', 'दस्तावेज़' या 'पैरेंट' तक नहीं पहुंच सकते हैं, इसलिए कोई डोम मैनिपुलेशन नहीं है। – nwellcome

+0

@ स्वागत नहीं, ऐसा नहीं है कि वे * संभव नहीं हैं :) मैं वेब श्रमिकों के साथ संभावनाओं के बारे में बहुत उत्साहित हूं। समस्या यह है कि वे व्यापक रूप से समर्थित नहीं हैं (अभी तक)। –