javascript - बिना फ़ंक्शन के Chrome संग्रहण API मान लौटाता है




function google-chrome-extension (2)

  1. chrome.storage.sync.get में कोई लौटाया गया मान नहीं है, जो बताता है कि क्यों आप किसी चीज़ को कॉल करते समय undefined हो जाएंगे

    var a = chrome.storage.sync.get({"disableautoplay": true});
  2. chrome.storage.sync.get भी एक अतुल्यकालिक विधि है, जो बताती है कि जब तक आप कॉलबैक फ़ंक्शन के अंदर इसका उपयोग नहीं करते हैं, तब निम्न कोड में undefined क्यों होगा।

    var a;
    window.onload = function(){
        chrome.storage.sync.get({"disableautoplay": true}, function(e){
            // #2
            a = e.disableautoplay; // true or false
        });
        // #1
        a; // undefined
    }

पिछले दो दिनों से मैं क्रोम अतुल्यकालिक भंडारण के साथ काम कर रहा हूं। यदि आपके पास कोई फ़ंक्शन है तो यह "ठीक" काम करता है। (नीचे की तरह):

chrome.storage.sync.get({"disableautoplay": true}, function(e){
console.log(e.disableautoplay);
});

मेरी समस्या यह है कि मैं जो कर रहा हूं उसके साथ एक फ़ंक्शन का उपयोग नहीं कर सकता। मैं इसे केवल लौटना चाहता हूं, जैसे लोकलस्टोरीज कर सकते हैं। कुछ इस तरह:

var a = chrome.storage.sync.get({"disableautoplay": true});

या

var a = chrome.storage.sync.get({"disableautoplay": true}, function(e){
    return e.disableautoplay;
});

मैंने एक लाख संयोजन की कोशिश की है, यहां तक ​​कि एक सार्वजनिक चर और सेटिंग भी सेट कर रहा है:

var a;
window.onload = function(){
    chrome.storage.sync.get({"disableautoplay": true}, function(e){
    a = e.disableautoplay;
});
}

कुछ भी काम नहीं करता है। यह सब तब तक अपरिभाषित रहता है जब तक कि कोड संदर्भित यह प्राप्त करने के कार्य के अंदर नहीं है, और यह मेरे लिए बेकार है। मैं केवल एक चर के रूप में एक मूल्य वापस करने में सक्षम होना चाहता हूं।

क्या यह भी संभव है?

संपादित करें: यह प्रश्न डुप्लिकेट नहीं है, कृपया मुझे यह बताने की अनुमति दें कि:

1: विशेष रूप से यह पूछने के लिए कोई अन्य पोस्ट नहीं हैं (मैंने दो दिन पहले देखे, सिर्फ मामले में)।

2: मेरे सवाल का अभी भी जवाब नहीं मिला है। हाँ, Chrome स्टोरेज अतुल्यकालिक है, और हाँ, यह मान वापस नहीं करता है। यही समस्या है। मैं नीचे विस्तृत हूँ ...

मुझे chrome.storage.sync.get फ़ंक्शन के बाहर एक संग्रहीत मान प्राप्त करने में सक्षम होने की आवश्यकता है। I -cannot- लोकलस्टोरेज का उपयोग करें, क्योंकि यह url स्पेसिफिक है, और क्रोम एक्सटेंशन के ब्राउजर_एक्शन पेज और बैकग्राउंड.जेएस दोनों से समान मानों को एक्सेस नहीं किया जा सकता। मैं एक स्क्रिप्ट के साथ एक मूल्य संग्रहीत नहीं कर सकता और इसे दूसरे के साथ एक्सेस कर सकता हूं। उनका अलग से इलाज किया जाता है।

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

जैसे लोकलस्टोरेज कैसे कर सकते हैं

if(localStorage.getItem("disableautoplay") == true);

की तर्ज पर कुछ करने के लिए कुछ रास्ता बनाना होगा

if(chrome.storage.sync.get("disableautoplay") == true);

मुझे लगता है कि यह आसान नहीं होगा, लेकिन यह सबसे अच्छा तरीका है जो मैं इसे समझा सकता हूं।

मैं हर पोस्ट को इस तरह से करने के लिए कहता हूं:

chrome.storage.sync.get({"disableautoplay": true, function(i){
    console.log(i.disableautoplay);
    //But the info is worthless to me inside this function.
});
//I need it outside this function.

ठीक है, ठीक है, आप अपने प्रश्न के अनुरूप उत्तर प्राप्त करें। यह अभी भी 90% लंबा स्पष्टीकरण होगा कि आप आसन के आसपास क्यों नहीं पहुंच सकते, लेकिन मेरे साथ सहन करें - यह आपको सामान्य रूप से मदद करेगा। मैं वादा करता हूँ कि अंत में chrome.storage लिए कुछ उचित है।

इससे पहले कि हम शुरू करते हैं, मैं इसके लिए विहित लिंक दोहराऊंगा:

तो, आइए, जेएस की विषमता पर चर्चा करें।

धारा 1: यह क्या है?

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

दूसरा, यह समझना महत्वपूर्ण है कि जावास्क्रिप्ट एकल-थ्रेडेड है। रनटाइम वातावरण द्वारा बनाए रखा गया एक ईवेंट लूप है; यदि कोई घटना होने पर कुछ अन्य कोड निष्पादित होता है, तो उस घटना को वर्तमान कोड समाप्त होने पर संसाधित होने के लिए एक कतार में डाल दिया जाता है।

इस कोड पर एक नज़र डालें:

var clicks = 0;

someCode();
element.addEventListener("click", function(e) {
  console.log("Oh hey, I'm clicked!");
  clicks += 1;
});
someMoreCode();

तो, यहाँ क्या हो रहा है? जैसे ही यह कोड निष्पादित होता है, जब निष्पादन पहुंच जाता है .addEventListener , निम्न होता है: रनटाइम वातावरण को सूचित किया जाता है कि जब घटना होती है ( element पर क्लिक किया जाता है), तो इसे हैंडलर फ़ंक्शन को कॉल करना चाहिए।

यह समझना महत्वपूर्ण है (हालांकि इस विशेष मामले में यह काफी स्पष्ट है) कि इस बिंदु पर फ़ंक्शन नहीं चलाया जाता है। यह बाद में ही चलेगा, जब वह घटना होगी। जैसे ही रनटाइम स्वीकार करता है 'मैं चलाऊंगा (या "कॉल बैक", इसलिए नाम "कॉलबैक") यह स्वीकार करता है कि ऐसा होने पर।' अगर कुछ someMoreCode() clicks को एक्सेस करने की कोशिश clicks , तो यह 0 होगा, 1 नहीं।

इसे एसिंक्रोनसिटी कहा जाता है , क्योंकि यह कुछ ऐसा है जो वर्तमान निष्पादन प्रवाह के बाहर होगा।

धारा 2: इसकी आवश्यकता क्यों है, या तुल्यकालिक एपीआई क्यों मर रहे हैं?

अब, एक महत्वपूर्ण विचार। मान लीजिए कि someMoreCode() वास्तव में एक बहुत लंबे समय तक चलने वाला कोड है। यदि एक क्लिक घटना तब भी घटित होती है, जब यह चल रहा होता है?

जावास्क्रिप्ट में इंटरप्ट की कोई अवधारणा नहीं है। रनटाइम यह देखेगा कि कोड निष्पादित हो रहा है, और इवेंट हैंडलर कॉल को कतार में रख देगा। कुछ पूरी तरह से खत्म होने से पहले हैंडलर निष्पादित नहीं करेगा।

जबकि एक क्लिक ईवेंट हैंडलर इस मायने में चरम है कि क्लिक होने की गारंटी नहीं है, यह बताता है कि आप अतुल्यकालिक ऑपरेशन के परिणाम की प्रतीक्षा क्यों नहीं कर सकते । यहाँ एक उदाहरण है जो काम नहीं करेगा:

element.addEventListener("click", function(e) {
  console.log("Oh hey, I'm clicked!");
  clicks += 1;
});
while(1) {
  if(clicks > 0) {
    console.log("Oh, hey, we clicked indeed!");
    break;
  }
}

आप अपने दिल की सामग्री पर क्लिक कर सकते हैं, लेकिन जिस कोड में clicks वृद्धि होगी वह धैर्यपूर्वक (गैर-समाप्ति) लूप को समाप्त करने की प्रतीक्षा कर रहा है। उफ़।

ध्यान दें कि कोड का यह टुकड़ा केवल इस कोड को फ्रीज नहीं करता है: प्रतीक्षा करते समय हर एक ईवेंट को अब हैंडल नहीं किया जाता है , क्योंकि केवल एक ईवेंट कतार / थ्रेड है। जावास्क्रिप्ट में केवल एक ही तरीका है कि अन्य हैंडलर को अपना काम करने दें: वर्तमान कोड को समाप्त करें, और रनटाइम को बताएं कि जब हम चाहते हैं तब क्या कॉल करना है

यही कारण है कि अतुल्यकालिक उपचार को कॉल के अन्य वर्ग पर लागू किया जाता है:

  • रनटाइम की आवश्यकता है, और जेएस नहीं, कुछ करने के लिए (उदाहरण के लिए डिस्क / नेटवर्क एक्सेस)
  • समाप्त करने की गारंटी है (चाहे सफलता या विफलता में)

आइए एक क्लासिक उदाहरण के साथ जाएं: AJAX कॉल। मान लें कि हम किसी URL से फ़ाइल लोड करना चाहते हैं।

  • मान लें कि हमारे वर्तमान कनेक्शन पर, रनटाइम उस फ़ाइल को फॉर्म में अनुरोध, डाउनलोड और प्रोसेस कर सकता है, जिसका उपयोग JS में 100ms में किया जा सकता है।
  • एक अन्य कनेक्शन पर, यह थोड़े बदतर है, यह 500ms लगेगा।
  • और कभी-कभी कनेक्शन वास्तव में खराब होता है, इसलिए रनटाइम 1000ms की प्रतीक्षा करेगा और टाइमआउट के साथ छोड़ देगा।

यदि हम इसे पूरा होने तक प्रतीक्षा करते हैं, तो हमारे पास एक परिवर्तनशील, अप्रत्याशित और अपेक्षाकृत लंबा विलंब होगा। जेएस प्रतीक्षा की वजह से काम करता है, अन्य सभी हैंडलर (जैसे यूआई) इस देरी के लिए अपना काम नहीं करेंगे, जिससे एक जमे हुए पृष्ठ की ओर बढ़ेगा।

परिचित लगता है? हाँ, यह बिल्कुल तुल्यकालिक XMLHttpRequest काम करता है । जेएस कोड में कुछ while(1) लूप के बजाय, यह अनिवार्य रूप से रनटाइम कोड में होता है - चूंकि जावास्क्रिप्ट अन्य कोड को क्रियान्वित नहीं कर सकता है जबकि यह प्रतीक्षा कर रहा है।

हां, यह कोड के एक परिचित रूप की अनुमति देता है:

var file = get("http://example.com/cat_video.mp4");

लेकिन ठंड की एक भयानक, भयानक लागत पर। एक लागत इतनी भयानक है कि, वास्तव में, आधुनिक ब्राउज़र इस पदावनत को मानते हैं। यहाँ MDN पर इस विषय पर एक चर्चा है

अब localStorage पर देखते हैं। यह "रनटाइम के लिए समाप्ति कॉल" के वर्णन से मेल खाता है, और फिर भी यह तुल्यकालिक है। क्यूं कर?

इसे सीधे शब्दों में कहें: ऐतिहासिक कारण (यह एक बहुत पुराना विनिर्देश है)।

हालांकि यह निश्चित रूप से एक नेटवर्क अनुरोध की तुलना में अधिक अनुमानित है, localStorage अभी भी निम्नलिखित श्रृंखला की आवश्यकता है:

JS code <-> Runtime <-> Storage DB <-> Cache <-> File storage on disk

यह घटनाओं की एक जटिल श्रृंखला है, और पूरे JS इंजन को इसके लिए रोका जाना चाहिए। यह अस्वीकार्य प्रदर्शन माना जाता है

अब, Chrome API ग्राउंड अप से, प्रदर्शन के लिए डिज़ाइन किए गए हैं। आप अभी भी पुराने APIs जैसे chrome.extension में कुछ सिंक्रोनस कॉल देख सकते हैं, और जेएस (और इसलिए सिंक्रोनस के रूप में समझ में आता है) पर कॉल किए जाते हैं, लेकिन chrome.storage (अपेक्षाकृत) नया है।

जैसे, यह प्रतिमान को गले लगाता है "मैं आपकी कॉल को स्वीकार करता हूं और परिणाम के साथ वापस आ जाएगा, अब कुछ उपयोगी इस बीच करें" यदि रनटाइम के साथ कुछ करने में देरी हो। XMLHttpRequest के विपरीत, उन कॉल का कोई समकालिक संस्करण नहीं है।

डॉक्स का हवाला देते हुए:

यह [ chrome.storage ] थोक पढ़ने और लिखने के कार्यों के साथ अतुल्यकालिक है, और इसलिए अवरुद्ध और धारावाहिक localStorage एपीआई की तुलना में तेज़ है

धारा 3: अतुल्यकालिकता को गले लगाने के लिए कैसे?

अतुल्यकालिकता से निपटने का क्लासिक तरीका कॉलबैक चेन हैं।

मान लें कि आपके पास निम्न तुल्यकालिक कोड है:

var result = doSomething();
doSomethingElse(result);

मान लीजिए कि, अब, doSomething असिंक्रोनस है। फिर यह बन जाता है:

doSomething(function(result) {
  doSomethingElse(result);
});

लेकिन क्या होगा अगर यह और भी जटिल है? यह कहें:

function doABunchOfThings() {
  var intermediate = doSomething();
  return doSomethingElse(intermediate);
}

if (doABunchOfThings() == 42) {
  andNowForSomethingCompletelyDifferent()
}

खैर .. इस मामले में आपको कॉलबैक में यह सब स्थानांतरित करने की आवश्यकता है। return कॉल बन जाना चाहिए।

function doABunchOfThings(callback) {
  doSomething(function(intermediate) {
    callback(doSomethingElse(intermediate));
  });
}

doABunchOfThings(function(result) {
  if (result == 42) {
    andNowForSomethingCompletelyDifferent();
  }
});

यहां आपके पास कॉलबैक की एक श्रृंखला है: doABunchOfThings कॉल doSomething तुरंत कॉल doSomething है, जो कि समाप्त हो जाता है, लेकिन कुछ समय बाद doSomethingElse कॉल doSomethingElse , जिसके परिणाम को किसी अन्य कॉलबैक के माध्यम से खिलाया जाता है।

जाहिर है, इस की लेयरिंग गड़बड़ हो सकती है। खैर, किसी ने नहीं कहा कि जावास्क्रिप्ट एक अच्छी भाषा है .. वेलकम टू कॉलबैक हेल

इसे और अधिक प्रबंधनीय बनाने के लिए उपकरण हैं, उदाहरण के लिए Promises । मैं उनके बारे में यहां चर्चा नहीं करूंगा (अंतरिक्ष से बाहर जाना), लेकिन वे मौलिक "यह कोड केवल बाद में चलेगा" भाग को नहीं बदलते हैं।

धारा TL; DR: मैं बिल्कुल भंडारण तुल्यकालिक, पड़ाव होना चाहिए!

कभी-कभी एक तुल्यकालिक भंडारण के वैध कारण होते हैं। उदाहरण के लिए, webRequest API अवरुद्ध कॉल प्रतीक्षा नहीं कर सकती। या कॉलबैक हेल आपको महंगा पड़ने वाला है।

आप जो कर सकते हैं, वह अतुल्यकालिक chrome.storage का एक तुल्यकालिक कैश है। यह कुछ लागतों के साथ आता है, लेकिन यह असंभव नहीं है।

विचार करें:

var storageCache = {};
chrome.storage.sync.get(null, function(data) {
  storageCache = data;
  // Now you have a synchronous snapshot!
});
// Not HERE, though, not until "inner" code runs

यदि आप अपने सभी इनिशियलाइज़ेशन कोड को एक फंक्शन init() में रख सकते हैं, तो आपके पास यह है:

var storageCache = {};
chrome.storage.sync.get(null, function(data) {
  storageCache = data;
  init(); // All your code is contained here, or executes later that this
});

जब तक init() कोड कोड निष्पादित हो जाता है, और बाद में जब कोई भी घटना जो init() में हैंडलर को सौंपी जाती है , storageCache पॉपुलेट हो जाएगा। आपने एक कॉलबैक में एसिंक्रोनसिटी को कम कर दिया है।

बेशक, यह केवल एक स्नैपशॉट है कि स्टोरेज को निष्पादित करने के समय क्या दिखता है get() । यदि आप संग्रहण के साथ सामंजस्य बनाए रखना चाहते हैं, तो आपको chrome.storage.onChanged घटनाओं के माध्यम से storageCache chrome.storage.onChanged अपडेट सेट करना होगा। जेएस के एकल-घटना-लूप प्रकृति के कारण, इसका मतलब है कि कैश केवल तब अपडेट किया जाएगा जब आपका कोड नहीं चलता है, लेकिन कई मामलों में यह स्वीकार्य है।

इसी तरह, यदि आप स्टोरेज storageCache में वास्तविक स्टोरेज में बदलाव करना चाहते हैं, तो स्टोरेज storageCache['key'] सेट करना storageCache['key'] पर्याप्त नहीं है। आपको एक set(key, value) शिम लिखना होगा set(key, value) जो कि BOTH storageCache और शेड्यूल a (एसिंक्रोनस) chrome.storage.sync.set को लिखता है।

उन पर अमल करना एक अभ्यास के रूप में शेष है।





google-chrome-storage