2017-04-06 4 views
0

다음 json이 API 호출에서 반환되었습니다. 특정 유형의 이벤트가 특정 제품에 대해 로깅되었는지 확인하고 해당 메시지가 올바른 메시지를 반환하고 클릭 핸들러를 종료하는 경우 그렇지 않으면 계속 진행합니다. 이 검사를 수행하려면 hasEvent이라는 기능이 있습니다. 그러나이 함수를 someOtherFunction에서 호출 할 때 검사가 true 일 때도 메시지가 반환되지 않습니까?jQuery - 콜백이 작동하지 않습니다.

{ 
    "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; 
    } 
} 

위의 코드에 어떤 문제가 있습니까?

* UPDATE * 내가 경고가 표시 얻을 경우, 나는 다음 클릭 핸들러를 종료 어떻게 지금 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

'// 클릭 이벤트 핸들러 종료 '가 잘못되었습니다. 또한'//이벤트가없는 경우에만 다른 것들을해라 .'도 콜백에 있어야한다. gogoasynchronouslogic –

답변

0

코드에 문제가 있다는 것입니다 :이 이벤트를하고 경고가 표시 만약 내가 핸들러를 종료 할 - 단순히 클릭 처리기 내부의 모든 작업이 완료 될 때까지 내가 원하는하지 않은 계속 실행 다음 $.getJSON은 비동기식입니다. 즉, 코드를 실행하면 다음 코드 행이 실행되기 전에 완료되지 않는 작업이 시작됩니다. 완료되면 .done에 전달 된 콜백이 실행되지만 그 시간에는 다른 코드 대부분이 이미 실행됩니다. 즉, hasEvents에 전화 할 때 msgundefined으로 초기화 한 다음 getEvents을 호출하면 ajax 호출이 다시 수신 될 때 호출됩니다. 그러나 해당 콜백이 즉시 실행되지 않으므로 hasEvents이 계속 실행되고 msg을 반환합니다.이 값은 여전히 ​​undefined과 같으며 Javascript에서는 위조 된 값입니다. 즉, Ajax 호출이 돌아오고 콜백이 실행될 때도 hasEvent(productType)이 이미 false로 평가되었습니다.

하나의 가능한 솔루션은 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

메시지와 함께 콜백을 반환하고 이벤트 처리기를 끝내기 위해 hasEvent 함수를 어떻게 변경해야하는지 모르겠습니다. 설명 할 코드를 추가 할 수 있습니까? 나는 다음과 같은 시도했다 - 업데이트 된 게시물하지만 작동하지 않는다? – adam78

+0

아무 것도 기록되지 않거나 경고가 표시되지 않습니까? – Griffin

+0

경고를 받지만 값은 정의되지 않습니다. 또한 콘솔에서 내 'hasEvent'함수 안에있는 라인에 대해서'\t 콜백 함수가 아니다 : return callback (msg);'라는 에러 메시지를 받는다. – adam78