जावास्क्रिप्ट में लॉक कैसे लागू करें


83

के बराबर कुछ कैसे हो सकता है lockC # में जावास्क्रिप्ट में कैसे लागू किया जा सकता है?

इसलिए, यह समझाने के लिए कि मैं एक साधारण उपयोग के मामले में क्या सोच रहा हूं:

उपयोगकर्ता क्लिक बटन BBएक ऑनक्लिक घटना को उठाता है। अगर Bमें है event-stateघटना प्रतीक्षा करता है के लिए Bमें होने की ready-stateप्रचार से पहले। यदि Bमें है ready-state, Bबंद है और करने के लिए सेट है event-state, तो घटना का प्रचार करता है। जब ईवेंट का प्रचार पूरा हो जाता है, तब Bसेट किया जाता हैready-state

मैं देख सकता था कि कक्षा को जोड़कर और हटाकर, इस के करीब कैसे कुछ किया जा सकता है ready-state कि बटन । हालांकि, समस्या यह है कि एक उपयोगकर्ता चर सेट करने की तुलना में तेजी से एक पंक्ति में दो बार एक बटन पर क्लिक कर सकता है, इसलिए लॉक पर यह प्रयास कुछ परिस्थितियों में विफल हो जाएगा।

क्या कोई जानता है कि एक ताला कैसे लागू किया जाए जो जावास्क्रिप्ट में विफल नहीं होगा?


1
जेएस निष्पादन (जैसे IE9 में) के समानांतर होने वाले उत्तर की सराहना की जाएगी।
ऑरेंजडॉग

@smart इसलिए आप वर्तमान ईवेंट के प्रसार को अस्थायी रूप से तब तक रोकना चाहते हैं जब तक कि किसी पिछले ईवेंट का प्रचार पूरा न हो जाए। मुझे नहीं लगता कि ऐसा किया जा सकता है। आप ऐसा कर सकते हैं: ईवेंट को छोड़ दें और फिर एक और फायर करें जब पिछले ईवेंट का प्रचार समाप्त हो गया हो।
इमे विद मरा

@ ऑरेंजडॉग - मैंने केवल सुना है IE9 संकलन के लिए एक समर्पित कोर का उपयोग करने की कोशिश करता है, समानांतर निष्पादन के बारे में कुछ भी नहीं, क्या आप एक स्रोत का हवाला दे सकते हैं?
ब्रैंडन

1
@ ब्रेंडन - इसका मतलब यह हो सकता है, जैसा कि आप सुझाव देते हैं, रेंडरर के समानांतर, बल्कि खुद के समानांतर।
ऑरेंजडॉग

जवाबों:


85

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

var functionLock = false;
var functionCallbacks = [];
var lockingFunction = function (callback) {
    if (functionLock) {
        functionCallbacks.push(callback);
    } else {
        $.longRunning(function(response) {
             while(functionCallbacks.length){
                 var thisCallback = functionCallbacks.pop();
                 thisCallback(response);
             }
        });
    }
}

आप DOM ईवेंट श्रोताओं या एक पबस्यूब समाधान का उपयोग करके भी इसे लागू कर सकते हैं।


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

2
+1 - यह देखते हुए कि Node.js (जावास्क्रिप्ट वेब सर्वर) को जावास्क्रिप्ट के लोन-थ्रेड और कॉलबैक तंत्र का लाभ उठाने के लिए बनाया गया था, मैं सहमत हूँ कि आपको किसी संपत्ति को लॉक करने के बारे में चिंता करने की ज़रूरत नहीं है क्योंकि कोई दौड़ की स्थिति नहीं होगी।
फेंटन

4
क्या पुस्तकालय $ है। यह (वर्तमान) jQuery में नहीं है।
क्वांटम 7

3
जब functionLock सेट होना चाहिए?
एल्टन गार्सिया डे सैन्टाना

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

32

जावास्क्रिप्ट एक बहुत कुछ अपवादों के साथ है ( XMLHttpRequest onreadystatechangeफ़ायरफ़ॉक्स के कुछ संस्करणों में हैंडलर) इवेंट-लूप समवर्ती । इसलिए आपको इस मामले में लॉक करने की चिंता नहीं करनी चाहिए।

जावास्क्रिप्ट में एक "इवेंट लूप" पर आधारित एक संगामिति मॉडल है। यह मॉडल सी या जावा जैसी अन्य भाषाओं के मॉडल से काफी अलग है।

...

जावास्क्रिप्ट रनटाइम में एक संदेश कतार होती है, जो संसाधित होने वाले संदेशों की एक सूची है। प्रत्येक संदेश के लिए एक समारोह जुड़ा हुआ है। जब स्टैक खाली होता है, तो एक संदेश कतार से बाहर ले जाया जाता है और संसाधित किया जाता है।प्रसंस्करण में संबंधित फ़ंक्शन को कॉल करना होता है (और इस तरह एक प्रारंभिक स्टैक फ्रेम बनाना) संदेश प्रसंस्करण समाप्त हो जाता है जब स्टैक फिर से खाली हो जाता है।

...

किसी भी संदेश को संसाधित करने से पहले प्रत्येक संदेश को पूरी तरह से संसाधित किया जाता है। यह आपके प्रोग्राम के बारे में तर्क करते समय कुछ अच्छे गुण प्रदान करता है, इस तथ्य सहित कि जब भी कोई फ़ंक्शन चलता है, तो यह पूर्व-खाली नहीं हो सकता है और किसी भी अन्य कोड के चलने से पहले पूरी तरह से चलेगा (और डेटा को संशोधित कर सकता है)। यह C से भिन्न है, उदाहरण के लिए, जहाँ यदि कोई कार्य थ्रेड में चलता है, तो इसे किसी अन्य कोड को किसी अन्य थ्रेड में चलाने के लिए किसी भी बिंदु पर रोका जा सकता है।

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

ईवेंट-लूप कंसीडर पर अधिक लिंक के लिए, E देखें


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

11

मेरे पास सफलता म्यूटेक्स-वादा है

मैं अन्य उत्तरों से सहमत हूं कि आपको अपने मामले में लॉक करने की आवश्यकता नहीं है। लेकिन यह सच नहीं है कि किसी को जावास्क्रिप्ट में लॉकिंग की आवश्यकता नहीं है। बाहरी संसाधनों को एक्सेस करते समय आपको पारस्परिक विशिष्टता की आवश्यकता होती है जो संगामिति को संभाल नहीं पाते हैं।


बहुत जरूरी बात धन्यवाद।
पापुलर पोलिनेन

6

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

मुझे संदेह है कि आपको अपने बटनों के बीच सिर्फ एक सेमाफोर (फ़्लैगिंग सिस्टम) सेट करने की आवश्यकता है।


1
क्या आपके पास जावास्क्रिप्ट में कार्यान्वित 'सेमीफोर / फ़्लैगिंग सिस्टम' के लिए ऐसे कोई उदाहरण या संसाधन हैं?
स्मार्टवॉमन

4
SO यहीं पर ढेर हो गया है यानी stackoverflow.com/questions/4194346/…
जेम्स वेस्टगेट

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

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

जवाब के लिए धन्यवाद। मैंने इसे सेटइंटरवल के साथ संयोजन में प्रसंस्करण के अंत में क्लिक इवेंट को कॉल करके हल किया। अंतराल को 1000 मिलीसेकंड पर सेट करना अब मैं अनुरोधों पर होस्ट सर्वर की सीमा का पालन करता हूं और प्रतिक्रिया वापस होने से पहले यह अजाक्स कॉल को बाहर नहीं करता है।
क्लॉस

2

ईवेंट को पूरा करने के बाद आप बटन को अक्षम क्यों नहीं करते और इसे सक्षम करते हैं?

<input type="button" id="xx" onclick="checkEnableSubmit('true');yourFunction();">

<script type="text/javascript">

function checkEnableSubmit(status) {  
  document.getElementById("xx").disabled = status;
}

function yourFunction(){

//add your functionality

checkEnableSubmit('false');
}

</script>

हैप्पी कोडिंग !!!


0

मेरे मामले के अनुसार जोशवर के जवाब के अलावा कुछ;

var functionCallbacks = [];
    var functionLock = false;
    var getData = function (url, callback) {
                   if (functionLock) {
                        functionCallbacks.push(callback);
                   } else {
                       functionLock = true;
                       functionCallbacks.push(callback);
                        $.getJSON(url, function (data) {
                            while (functionCallbacks.length) {
                                var thisCallback = functionCallbacks.pop();
                                thisCallback(data);
                            }
                            functionLock = false;
                        });
                    }
                };

// Usage
getData("api/orders",function(data){
    barChart(data);
});
getData("api/orders",function(data){
  lineChart(data);
});

केवल एक एपीआई कॉल होगी और ये दोनों फ़ंक्शन समान परिणाम का उपभोग करेंगे।


0

जेएस में अभी भी ताले का उपयोग होता है। मेरे अनुभव में मुझे केवल AJAX कॉल करने वाले तत्वों पर क्लिक करने से रोकने के लिए ताले का उपयोग करने की आवश्यकता थी। यदि आपके पास AJAX कॉल के लिए लोडर सेट है तो इसकी आवश्यकता नहीं है (साथ ही क्लिक करने के बाद बटन को अक्षम करना)। लेकिन या तो यहां तरीका है जो मैंने लॉक करने के लिए उपयोग किया है:

var LOCK_INDEX = [];
function LockCallback(key, action, manual) {
    if (LOCK_INDEX[key])
        return;
    LOCK_INDEX[key] = true;
    action(function () { delete LOCK_INDEX[key] });
    if (!manual)
        delete LOCK_INDEX[key];
}

उपयोग:

मैनुअल अनलॉक (आमतौर पर XHR के लिए)

LockCallback('someKey',(delCallback) => { 
    //do stuff
    delCallback(); //Unlock method
}, true)

ऑटो अनलॉक

LockCallback('someKey',() => { 
    //do stuff
})

0

यहां एक सरल लॉक तंत्र है, जिसे क्लोजर के माध्यम से लागू किया गया है

const createLock = () => {

    let lockStatus = false

    const release = () => {
        lockStatus = false
    }

    const acuire = () => {
        if (lockStatus == true)
            return false
        lockStatus = true
        return true
    }
    
    return {
        lockStatus: lockStatus, 
        acuire: acuire,
        release: release,
    }
}

lock = createLock() // create a lock
lock.acuire() // acuired a lock

if (lock.acuire()){
  console.log("Was able to acuire");
} else {
  console.log("Was not to acuire"); // This will execute
}

lock.release() // now the lock is released

if(lock.acuire()){
  console.log("Was able to acuire"); // This will execute
} else {
  console.log("Was not to acuire"); 
}

lock.release() // Hey don't forget to release

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.