मेरे पास एक एपीआई कॉल से निम्नलिखित जेसन लौटा है। मैं यह जांचना चाहता हूं कि कुछ उत्पादों के लिए एक विशेष प्रकार का ईवेंट लॉग किया गया है और यदि यह सही है तो एक उपयुक्त संदेश लौटाएं और क्लिक हैंडलर से बाहर निकलें अन्यथा जारी रखें। इस जांच को करने के लिए मेरे पास hasEvent
नाम का एक फंक्शन है। लेकिन जब मैं इस फ़ंक्शन को someOtherFunction
से कॉल करता हूं तो चेक सही होने पर भी कोई संदेश वापस नहीं किया जाता है?
{
"item": {
"Event": [
{
"EventType": {
"Description": "New order"
},
"EventSubType": {
"Description": "Awaiting payment"
}
},
{
"EventType": {
"Description": "New order"
},
"EventSubType": {
"Description": "Dispatched"
}
}
],
"Errors": {
"Result": 0,
"Message": ""
},
"RecordCount": 2
}
}
var getEvents = function (callback) {
var orderId = $("#Id").val();
$.getJSON('api/events?id=' + orderId)
.done(function (data) {
callback(data);
}).fail(function (jqXHR, textStatus, err) {
return;
});
}
var hasEvent = function (productType, callback) {
var msg;
getEvents(function (data) {
_.find(data.item.Event, function (event) {
if (event.EventType.Description == 'New order' &&
event.EventSubType.Description == 'Dispatched' &&
productType = 'xyz') {
msg = 'Some message';
return true;
}
if (event.EventType.Description == 'New order' &&
event.EventSubType.Description == 'Awaiting payment' &&
productType = 'xyz') {
msg = 'A different message';
return true;
}
// Check for Some more conditions and return appropriate message
return false;
});
if (msg)
callback(msg);
});
}
var someOtherFunction = function () {
$('.myselector').click(function (e) {
var productType = $(this).attr("data-product-type");
hasEvent(productType, function(msg) {
alert(msg);
// exit click event handler
return;
});
// otherwise do some other stuff
return false;
}
}
उपरोक्त कोड में क्या गलत है?
* अद्यतन करें *
मैंने hasEvent
फ़ंक्शन में कॉलबैक जोड़कर ग्रिफिन समाधान के अनुसार कोड को अपडेट किया है, लेकिन अब अलर्ट प्रदर्शित होने पर मैं निम्नलिखित क्लिक हैंडलर से कैसे बाहर निकल सकता हूं। निम्नलिखित केवल तब तक निष्पादित करना जारी रखता है जब तक कि क्लिक हैंडलर के अंदर सभी क्रियाएं पूरी नहीं हो जातीं, जो कि मैं नहीं चाहता हूं - यदि ईवेंट और अलर्ट प्रदर्शित होते हैं तो मैं हैंडलर से बाहर निकलना चाहता हूं:
$('.myselector').click(function (e) {
var productType = $(this).attr("data-product-type");
hasEvent(productType, function(eventMsg) {
alert(msg);
// exit click event handler
return;
});
// Do some other stuff only if no events
return false;
}
1 उत्तर
आपके कोड में समस्या यह है कि $.getJSON
एसिंक्रोनस है, जिसका अर्थ है कि जब आप इसे निष्पादित करते हैं, तो यह एक ऐसा ऑपरेशन शुरू कर रहा है जो कोड की अगली पंक्ति के चलने से पहले पूरा नहीं होगा। जब यह पूरा हो जाता है, तो आपके द्वारा .done
को दिया गया कॉलबैक निष्पादित हो जाएगा, लेकिन उस समय में, आपका अधिकांश अन्य कोड पहले ही चल चुका होगा। इसका मतलब यह है कि जब आप hasEvents
को कॉल करते हैं, तो आप msg
से undefined
को इनिशियलाइज़ कर रहे हैं, फिर getEvents
को एक कॉलबैक पास कर रहे हैं, जिसे आपकी अजाक्स कॉल वापस आने पर कॉल किया जाएगा। हालांकि, चूंकि उस कॉलबैक को तुरंत निष्पादित नहीं किया जाएगा, hasEvents
जारी है और msg
लौटाता है, जो अभी भी undefined
के बराबर है, जो कि Javascript में एक गलत मान है। इसका मतलब यह है कि जब आपका अजाक्स कॉल वापस आता है और कॉलबैक निष्पादित होता है, तब भी hasEvent(productType)
का मूल्यांकन पहले ही गलत हो चुका है।
एक संभावित समाधान hasEvent
को दूसरा पैरामीटर देना होगा, जो एक कॉलबैक है। फिर अपने _.find
में, आप उस कॉलबैक को वापस करने के बजाय संदेश के साथ निष्पादित कर सकते हैं, जैसे:
var getEvents = function (callback) {
var orderId = $("#Id").val();
$.getJSON('api/events?id=' + orderId)
.done(function (data) {
callback(data);
}).fail(function (jqXHR, textStatus, err) {
return;
});
}
var hasEvent = function (productType, callback) {
var msg = null;
getEvents(function (data) {
_.find(data.item.Event, function (event) {
if (event.EventType.Description == 'New order' &&
event.EventSubType.Description == 'Dispatched' &&
productType = 'xyz') {
msg = 'Some message';
return true;
}
if (event.EventType.Description == 'New order' &&
event.EventSubType.Description == 'Awaiting payment' &&
productType = 'xyz') {
msg = 'A different message';
return true;
}
// Check for Some more conditions and return appropriate message
return false;
});
callback(msg);
});
}
var someOtherFunction = function () {
$('.myselector').click(function (e) {
var productType = $(this).attr("data-product-type");
hasEvent(productType, function(eventMsg) {
if (eventMsg) {
console.log(eventMsg);
alert(eventMsg);
} else {
console.log('there was no event!')
}
})
}
}
वैकल्पिक रूप से, अतुल्यकालिक jQuery फ़ंक्शन वादे लौटाते हैं, इसलिए आप इसके बजाय ऐसा कर सकते हैं:
var getEvents = function (callback) {
var orderId = $("#Id").val();
return $.getJSON('api/events?id=' + orderId);
}
var hasEvent = function (productType) {
return getEvents()
.then(function (data) {
var foundEvent = _.find(data.item.Event, function (event) {
if (event.EventType.Description == 'New order' &&
event.EventSubType.Description == 'Dispatched' &&
productType = 'xyz') {
}
// Check for Some more conditions and return appropriate message
return false; // if you don't return, it's undefined, which is a falsy value and has the same effect as returning false in _.find
});
return 'some message';
});
}
var someOtherFunction = function () {
$('.myselector').click(function (e) {
var productType = $(this).attr("data-product-type");
hasEvent(productType)
.then(function(eventMsg) {
console.log(eventMsg);
alert(eventMsg);
});
}
}
hasEvent
पर भेज रहे हैं, उसका पैरामीटर eventMsg
है, लेकिन आप कंसोल.लॉगिंग कर रहे हैं और msg
नामक एक वैरिएबल को अलर्ट कर रहे हैं। यह समझाएगा कि यह अपरिभाषित क्यों चेतावनी दे रहा है। हालांकि कॉलबैक त्रुटि के बारे में निश्चित नहीं है ...
hasEvent
फ़ंक्शन में मैंने कॉलबैक को _.find
विधि के बाहर ले जाया है जो call back is not a function
त्रुटि को ठीक करता है और अलर्ट प्रदर्शित करता है। हालांकि अगर कोई त्रुटि है तो मैं हैंडलर के अंदर किसी अन्य कोड को निष्पादित किए बिना अलर्ट प्रदर्शित करने के बाद $('.myselector').click(function (e) {..})
क्लिक इवेंट हैंडलर से बाहर निकलना चाहता हूं। यह कैसे हासिल किया जा सकता है?
संबंधित सवाल
नए सवाल
jquery
jQuery एक जावास्क्रिप्ट लाइब्रेरी है, जावास्क्रिप्ट टैग को जोड़ने पर भी विचार करें। jQuery एक लोकप्रिय क्रॉस-ब्राउज़र जावास्क्रिप्ट लाइब्रेरी है, जो दस्तावेज़ ऑब्जेक्ट मॉडल (DOM) ट्रैवर्सल, इवेंट हैंडलिंग, एनिमेशन और AJAX इंटरैक्शन को ब्राउज़रों की विसंगतियों को कम करके सुविधाजनक बनाता है। JQuery से संबंधित एक प्रश्न jQuery से संबंधित होना चाहिए, इसलिए jQuery को प्रश्न में कोड द्वारा उपयोग किया जाना चाहिए और कम से कम jQuery के उपयोग से संबंधित तत्वों को प्रश्न में होना चाहिए।
// exit click event handler
गलत है।// Do some other stuff only if no events
भी कॉलबैक में होना चाहिए। गोगोएसिंक्रोनसलॉजिक