मेरे पास एक एपीआई कॉल से निम्नलिखित जेसन लौटा है। मैं यह जांचना चाहता हूं कि कुछ उत्पादों के लिए एक विशेष प्रकार का ईवेंट लॉग किया गया है और यदि यह सही है तो एक उपयुक्त संदेश लौटाएं और क्लिक हैंडलर से बाहर निकलें अन्यथा जारी रखें। इस जांच को करने के लिए मेरे पास 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;
}
0
adam78 6 अप्रैल 2017, 17:15
// exit click event handler गलत है। // Do some other stuff only if no events भी कॉलबैक में होना चाहिए। गोगोएसिंक्रोनसलॉजिक
 – 
Kevin B
6 अप्रैल 2017, 21:53

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);
      });
  }
}
0
Griffin 6 अप्रैल 2017, 21:55
मुझे यकीन नहीं है कि मैं संदेश के साथ कॉलबैक वापस करने और ईवेंट हैंडलर से बाहर निकलने के लिए हैववेंट फ़ंक्शन को कैसे बदलता हूं? क्या आप कृपया समझाने के लिए कुछ कोड जोड़ सकते हैं। मैंने निम्नलिखित अद्यतन पोस्ट की कोशिश की है लेकिन यह काम नहीं करता है?
 – 
adam78
6 अप्रैल 2017, 18:03
तो कुछ भी लॉग या अलर्ट नहीं हो रहा है?
 – 
Griffin
6 अप्रैल 2017, 18:10
मुझे अलर्ट मिलता है लेकिन मूल्य अपरिभाषित है। कंसोल में भी मुझे त्रुटि मिलती है 'कॉल बैक एक फ़ंक्शन नहीं है: कॉलबैक (msg);' मेरे हैवेन्ट फ़ंक्शन के अंदर की रेखा के लिए।
 – 
adam78
6 अप्रैल 2017, 18:18
ओह ओह, ऐसा लगता है कि आप जिस कॉलबैक को hasEvent पर भेज रहे हैं, उसका पैरामीटर eventMsg है, लेकिन आप कंसोल.लॉगिंग कर रहे हैं और msg नामक एक वैरिएबल को अलर्ट कर रहे हैं। यह समझाएगा कि यह अपरिभाषित क्यों चेतावनी दे रहा है। हालांकि कॉलबैक त्रुटि के बारे में निश्चित नहीं है ...
 – 
Griffin
6 अप्रैल 2017, 18:32
मैंने कोड अपडेट किया है - मूल पोस्ट देखें। hasEvent फ़ंक्शन में मैंने कॉलबैक को _.find विधि के बाहर ले जाया है जो call back is not a function त्रुटि को ठीक करता है और अलर्ट प्रदर्शित करता है। हालांकि अगर कोई त्रुटि है तो मैं हैंडलर के अंदर किसी अन्य कोड को निष्पादित किए बिना अलर्ट प्रदर्शित करने के बाद $('.myselector').click(function (e) {..}) क्लिक इवेंट हैंडलर से बाहर निकलना चाहता हूं। यह कैसे हासिल किया जा सकता है?
 – 
adam78
6 अप्रैल 2017, 19:58