2015-11-12 7 views
5

मेरे पास एक फ़ंक्शन है, जो ऐसा लगता है।"फ्रीजिंग" ब्राउज़र को रोकने के लिए वादा का उपयोग करने के लिए प्रत्येक के लिए फिर से लिखना कैसे करें?

function() { 
     longArray.forEach(element => doSomethingResourceIntensive(element)) 
} 

क्योंकि सरणी लंबी है और फ़ंक्शन थोड़ा संसाधन गहन है, यह ब्राउज़र को फ्रीज करता है।

अब मैं वादा का उपयोग करके इसे फिर से लिखना चाहता हूं, इसलिए यह वही काम करता है, बस ब्राउज़र को ठंडा नहीं करता है, और मैं समाधान को सुरुचिपूर्ण और "ES6-y" बनाना चाहता हूं; आदर्श रूप से, जब सभी पुनरावृत्तियों को समाप्त किया गया तो कार्य वादा वापस कर देगा।

मुझे this question मिला, जहां इसे सेटटाइमआउट का उपयोग करने के साथ निपटाया गया है, लेकिन यह थोड़ा "un-ES6-y" लगता है, और यह वादा नहीं करता है।

मैं

function() { 
     return Promise.all(longArray.map(element => 
      Promise.resolve().then(() => doSomethingResourceIntensive(element)) 
    ) 
} 

ऐसा नहीं कर सकते, क्योंकि मैं लगातार वादों को चलाने के लिए की जरूरत है और मुझे यकीन है कि अगर यह वहाँ क्या होगा नहीं हूँ।

+0

क्या आपने 'setTimeout' का उपयोग करने और अंदर लूप को निष्पादित करने का प्रयास किया था? – jeerbl

+4

[वेब श्रमिक] (https://developer.mozilla.org/en-US/docs/Web/API/Worker) के बारे में क्या? – Andreas

+5

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

उत्तर

1

आपके द्वारा संदर्भित उत्तर सही है, आपको setTimeout की आवश्यकता है। एक वादे-चेन का उपयोग अकेले मदद नहीं करेगा क्योंकि .then चेन एक माइक्रोट्रैक कतार पर निष्पादित करते हैं, जो अधिकांश ब्राउज़रों में वर्तमान रन-टू-पूर्णता की पूंछ पर पूरी तरह से खाली हो जाते हैं। दूसरे शब्दों में, वे अभी भी चीजें जमा कर देंगे।

आप कुछ ES6-y चाहते हैं, मैं इस भरोसेमंद सहायक पर भरोसा करते हैं:

var wait = ms => new Promise(resolve => setTimeout(resolve, ms)); 

तो मैं ऐसा कर सकते हैं:

longArray.reduce((p, i) => p.then(() => doIntensiveStuff(i)).then(() => wait(5)), 
       Promise.resolve()); 

जब तक आप निश्चित रूप से श्रमिकों का उपयोग कर सकते हैं।

4

यदि आपको उत्तराधिकार में वादे चलाने की आवश्यकता है, तो आप .then कॉलों को श्रृंखलाबद्ध करना चाहते हैं। नहीं

function() { 
    return longArray.reduce((promise, el) => 
     promise.then(() => doSomethingResourceIntensive(el)), 
     Promise.resolve()); // Start with a clean promise! 
} 

इसके अलावा, काम के प्रकार तुम क्या पर निर्भर करता है, तो आप Web Workers है, जो एक और धागा में क्रियान्वित कर रहे हैं में देखने के लिए चाहते हो सकता है और इस तरह: आप सामान्य रूप से है कि साथ .reduce() करना पेज को ब्लॉक करें।

+0

यह बहुत ही आशाजनक प्रतीत होता है (कोई इरादा नहीं है), मैं शायद इसका उपयोग करूंगा। –

+0

का प्रयास करने के बाद मैं स्वीकार करूंगा कि मुझे लगता है कि आप 'वादे' से पहले 'वापसी' चूक गए थे। फिर ' – Sean

+0

@ सेन नहीं, मेरे पास अभी अनावश्यक घुंघराले ब्रैकेट और अर्धविराम थे। यदि केवल एक ही कथन है तो तीर फ़ंक्शन रिटर्न को संभालते हैं। –

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

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