2012-05-06 8 views
15

में बड़ी मात्रा में डालने से मैं अपने इंडेक्सड डीबी के ऑब्जेक्टस्टोर में कुछ ~ 35000 ऑब्जेक्ट्स को सहेजना चाहता हूं। मैं डालने के लिए नीचे कोड का उपयोग कर रहा हूँ।इंडेक्स डीडी के ऑब्जेक्टस्टोर ब्लॉक यूआई

AddListings = function (x2j_list_new, callback) { 
    var transaction = db.transaction(["listings"], IDBTransaction.READ_WRITE); 
    var count = 0; 
    transaction.oncomplete = function (event) { 
     if (callback) { 
      console.log('x2jShowListing Added ' + count + '/' + x2j_list_new.length); 
       callback([count, x2j_list_new.length]); 
      } 
    }; 
    transaction.onerror = function (e) { 
     console.log("myError: ", e); 
     if (callback) { 
      callback(false); 
     } 
    }; 
    var store = transaction.objectStore("listings"); 

    $.each(x2j_list_new, function (index0, item0) { 
     var request = store.put(item0); 
     request.onsuccess = function (event) { 
      count++; 
      // event.target.result 
      }; 
     }); 
    });   
}; 

उपरोक्त कोड ठीक काम करता है, लेकिन पाशन और ~ 35000 वस्तुओं से अधिक डालने यूआई ~ 200 सेकंड के लिए अनुत्तरदायी बना देता है। मैंने सोचा कि शायद मैं वेबवर्कर्स का उपयोग कर सकता हूं, लेकिन इंडेक्सड डीबी वेबवर्कर्स के अंदर उपलब्ध नहीं है। मैंने थोक डालने का रास्ता खोजने की कोशिश की, एक नहीं मिला। यूआई को अवरुद्ध किए बिना बड़ी मात्रा में वस्तुओं को सम्मिलित करने के बारे में कोई विचार?

+1

(http://stackoverflow.com/questions/ 8495687/स्प्लिट-एरे-इन-चंक्स) 500 का और [setInterval] का उपयोग करके (http://www.kryogenix.org/days/2009/07/03/not-blocking-the-ui-in-tight-javascript- लूप के बजाय लूप)। अब यूआई पहले से थोड़ा बेहतर प्रतिक्रिया देता है। – surya

उत्तर

28

से थोड़ा बेहतर प्रतिक्रिया देता है, आप सही रास्ते पर हैं, लेकिन आप ब्राउज़र को 35,000 ऑब्जेक्ट्स स्टोर करने के लिए कह रहे हैं इससे पहले कि उसे स्टोर करना समाप्त हो जाए। यहाँ कोड एक अनुरोध अगले शुरू करने (लेकिन एक ही लेन-देन का प्रयोग करके) से पहले खत्म करने के लिए के लिए जो एसिंक्रोनस रूप से इंतजार कर रहा है है: अब मैं [हिस्सा] में सरणी बंटवारे हूँ के लिए

openRequest = window.indexedDB.open("MyDatabase", 1); 
    openRequest.onerror = function(event) { 
     console.error(event); 
    }; 
    openRequest.onsuccess = function (event) { 
     var db = openRequest.result; 
     db.onerror = function(event) { 
      // Generic error handler for all errors targeted at this database's requests 
      console.error(event.target); 
      window.alert("Database error: " + event.target.wePutrrorMessage || event.target.error.name || event.target.error || event.target.errorCode); 
     }; 
     var transaction = db.transaction('item', "readwrite"); 
     var itemStore = transaction.objectStore("item"); 
     putNext(); 

     function putNext() { 
      if (i<items.length) { 
       itemStore.put(items[i]).onsuccess = putNext; 
       ++i; 
      } else { // complete 
       console.log('populate complete'); 
       callback(); 
      } 
     }   
    };  
+0

दिलचस्प सुझाव इस तरह से अजीब व्यवहार करता है। उत्सुक- कोई भी प्रदर्शन लाभ पर कोई भी बेंचमार्क चलाता है? –

+0

यह सुनिश्चित करने के लिए कि स्टोर में सभी आइटम ** वास्तव में ** हैं - 'credit.oncomplete 'ईवेंट की सदस्यता लें, जैसे smth:' credit.oncomplete = callback' – Kiril

+0

मैं नहीं देख सकता कि लेनदेन के अंत का निर्धारण कैसे करें , किसी को लेनदेन से एक स्टोर मिलता है तो एक या एक से अधिक रिकॉर्ड जोड़ें ... मैं इसे जोड़ने के बाद लेनदेन समाप्त कैसे कर सकता हूं? क्या कॉलबैक रिटर्न के बाद लेनदेन समाप्त होता है? इस रिकर्सिव कॉल में सभी प्रविष्टियों को जोड़ने के बाद कौन सा है? मुझे ऐसा लगता है – lisak

0

आप कॉलबैक का उपयोग कर सही सब कुछ कर रहे हैं।

वेबवर्कर एपीआई अभी तक किसी भी बड़े ब्राउज़र द्वारा लागू नहीं किया गया है। दिलचस्प बात यह है कि यह तुल्यकालिक होने की उम्मीद है। आपके द्वारा वर्णित सटीक कारण के लिए नियमित API एसिंक है - यह UI थ्रेड को अवरुद्ध नहीं करना चाहिए।

कॉलबैक का उपयोग करना लॉक अप से बचने का तरीका है, लेकिन 35k ऑब्जेक्ट्स पर आप स्पष्ट रूप से इस प्रतिमान को तोड़ रहे हैं। दुर्भाग्यवश, आईडीबी प्रदर्शन अभी तक मैंने देखा है कि बेंचमार्क से WebSQL के बराबर नहीं है।

क्रोम के स्तर डीबी के साथ कुछ नए प्रयोगात्मक बैकएंड (एफएफ SQLite है) लेकिन मुझे लगता है कि आपका अनुभव साबित करता है कि सुधार के लिए कुछ जगह है।

0

मेरी तरफ से जंगली अनुमान, लेकिन यदि वेबस्क्लुएल "पृष्ठभूमि पृष्ठ" के रूप में जाना जाता है, से उपलब्ध है, और यह मानते हुए कि फ्रंट-बैकपेज के बीच मैसेजिंग की बैंडविड्थ उसी तरह यूआई को लॉक नहीं करती है, शायद इंट्रा पेज संदेश वाला एक पृष्ठभूमि पृष्ठ का उपयोग किया जा सकता है?

+0

मुझे एहसास है कि यह लूप के लिए है जो ब्लॉक यूआई का कारण बन रहा है। मेरी इच्छा है कि नियमित अंतराल में ब्राउज़र को पिंग करने का कोई तरीका था, इसलिए ऐसा नहीं लगता कि यह – surya

+0

पारंपरिक जीयूआई प्रोग्रामिंग में, आप यह पता लगा सकते हैं कि ब्राउज़र "निष्क्रिय" कब होता है और आपके बड़े फोर लूप में एक और चरण निष्पादित करता है। दुर्भाग्यवश, निष्क्रिय स्थिति का पता लगाना जावास्क्रिप्ट में आसान नहीं है, लेकिन इसे अनुकरण करने के लिए हैक्स हैं। उदाहरण के लिए http://stackoverflow.com/questions/667555/detecting-idle-time-in-javascript- स्पष्ट रूप से। –

0

मैं 500 के हिस्सों में सरणी को विभाजित कर रहा हूं और लूप के बजाय setTimeout का उपयोग कर रहा हूं। अब यूआई

+0

मैं एकाधिक ईवेंट लूप कार्यों से इंडेक्सड डीबी तक पहुंचने की अनुशंसा नहीं करता हूं। यह – lisak

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