调用递归时无法访问成功函数 ajax
Cant access success function when call recursive ajax
我正在构建一个具有推送通知功能的系统并使用 Jersey 创建 API。
我阅读了一篇关于彗星方法的 article,最后得到以下代码:
Index.js
function checkExamNotification() {
$.ajax({
url: contextPath + '/api/notification/checkExamNotification',
type: 'get',
data: {
accountId: accountId,
sessionId: sessionId
},
success: function (res) {
console.log("success");
displayNumberOfNotification();
checkExamNotification();
},
error: function (jqXHR, textStatus, errorThrown) {
if (textStatus === "timeout") {
checkExamNotification();
}
}
});
}
$(document).ready(function () {
$.ajaxSetup({
timeout: 1000*60*3
});
checkExamNotification();
});
查看考试通知API
@GET
@Path("/checkExamNotification")
public Response checkExamNotification(@QueryParam("accountId") int accountId, @QueryParam("sessionId") String sessionId) throws InterruptedException {
if (memCachedClient.checkSession(sessionId, accountId)) {
while (!examNotificationQueue.hasItems()) {
Thread.sleep(5000);
}
ExamNotificationQueueItemModel examNotificationQueueItemModel = examNotificationQueue.dequeue();
if (examNotificationQueueItemModel.getAccountId() == accountId) {
LOGGER.info("[START] Check exam notification API");
LOGGER.info("Account ID: " + accountId);
LOGGER.info("Get notification with exam ID: " + examNotificationQueueItemModel.getExamId());
ExamEntity exam = examDAO.findById(examNotificationQueueItemModel.getExamId());
NotificationEntity notification = notificationDAO.findByExamId(exam.getExamid());
notification.setSend(1);
notificationDAO.getEntityManager().getTransaction().begin();
notificationDAO.update(notification);
notificationDAO.getEntityManager().getTransaction().commit();
LOGGER.info("[END]");
String result = gson.toJson(examNotificationQueueItemModel);
return Response.status(200).entity(result).build();
} else {
examNotificationQueue.enqueue(examNotificationQueueItemModel);
Thread.sleep(5000);
checkExamNotification(accountId, sessionId);
}
}
return Response.status(200).entity(gson.toJson("timeout")).build();
}
根据我的调试,API 确实完成了 return 但成功事件有时没有触发。
是的,有时控制台日志成功但有时不成功。
谁能给我解释一下这个案例?
提前致谢。任何帮助将不胜感激。
关注@peeskillet 评论后确定。这是我的最终代码。
查看考试通知API
@GET
@Produces(SseFeature.SERVER_SENT_EVENTS)
@Path("/checkExamNotification")
public EventOutput checkExamNotification(@QueryParam("accountId") final int accountId, @QueryParam("sessionId") final String sessionId) {
final EventOutput eventOutput = new EventOutput();
if (memCachedClient.checkSession(sessionId, accountId)) {
new Thread(new Runnable() {
public void run() {
try {
if (examNotificationQueue.hasItems()) {
ExamNotificationQueueItemModel examNotificationQueueItemModel = examNotificationQueue.dequeue();
if (examNotificationQueueItemModel.getAccountId() == accountId) {
LOGGER.info("[START] Check exam notification API");
LOGGER.info("Account ID: " + accountId);
LOGGER.info("Get notification with exam ID: " + examNotificationQueueItemModel.getExamName());
String result = gson.toJson(examNotificationQueueItemModel);
final OutboundEvent.Builder eventBuilder
= new OutboundEvent.Builder();
eventBuilder.data(result);
final OutboundEvent event = eventBuilder.build();
eventOutput.write(event);
LOGGER.info("[END]");
} else {
examNotificationQueue.enqueue(examNotificationQueueItemModel);
}
}
} catch (IOException e) {
throw new RuntimeException(
"Error when writing the event.", e);
} finally {
try {
eventOutput.close();
} catch (IOException ioClose) {
throw new RuntimeException(
"Error when closing the event output.", ioClose);
}
}
}
}).start();
}
return eventOutput;
}
Index.js
function checkExamNotification() {
var url = contextPath + '/api/notification/checkExamNotification?accountId=' + accountId + '&sessionId=' + sessionId;
var source = new EventSource(url);
source.onmessage = function (event) {
displayNumberOfNotification();
};
}
我正在构建一个具有推送通知功能的系统并使用 Jersey 创建 API。
我阅读了一篇关于彗星方法的 article,最后得到以下代码:
Index.js
function checkExamNotification() {
$.ajax({
url: contextPath + '/api/notification/checkExamNotification',
type: 'get',
data: {
accountId: accountId,
sessionId: sessionId
},
success: function (res) {
console.log("success");
displayNumberOfNotification();
checkExamNotification();
},
error: function (jqXHR, textStatus, errorThrown) {
if (textStatus === "timeout") {
checkExamNotification();
}
}
});
}
$(document).ready(function () {
$.ajaxSetup({
timeout: 1000*60*3
});
checkExamNotification();
});
查看考试通知API
@GET
@Path("/checkExamNotification")
public Response checkExamNotification(@QueryParam("accountId") int accountId, @QueryParam("sessionId") String sessionId) throws InterruptedException {
if (memCachedClient.checkSession(sessionId, accountId)) {
while (!examNotificationQueue.hasItems()) {
Thread.sleep(5000);
}
ExamNotificationQueueItemModel examNotificationQueueItemModel = examNotificationQueue.dequeue();
if (examNotificationQueueItemModel.getAccountId() == accountId) {
LOGGER.info("[START] Check exam notification API");
LOGGER.info("Account ID: " + accountId);
LOGGER.info("Get notification with exam ID: " + examNotificationQueueItemModel.getExamId());
ExamEntity exam = examDAO.findById(examNotificationQueueItemModel.getExamId());
NotificationEntity notification = notificationDAO.findByExamId(exam.getExamid());
notification.setSend(1);
notificationDAO.getEntityManager().getTransaction().begin();
notificationDAO.update(notification);
notificationDAO.getEntityManager().getTransaction().commit();
LOGGER.info("[END]");
String result = gson.toJson(examNotificationQueueItemModel);
return Response.status(200).entity(result).build();
} else {
examNotificationQueue.enqueue(examNotificationQueueItemModel);
Thread.sleep(5000);
checkExamNotification(accountId, sessionId);
}
}
return Response.status(200).entity(gson.toJson("timeout")).build();
}
根据我的调试,API 确实完成了 return 但成功事件有时没有触发。
是的,有时控制台日志成功但有时不成功。
谁能给我解释一下这个案例?
提前致谢。任何帮助将不胜感激。
关注@peeskillet 评论后确定。这是我的最终代码。
查看考试通知API
@GET
@Produces(SseFeature.SERVER_SENT_EVENTS)
@Path("/checkExamNotification")
public EventOutput checkExamNotification(@QueryParam("accountId") final int accountId, @QueryParam("sessionId") final String sessionId) {
final EventOutput eventOutput = new EventOutput();
if (memCachedClient.checkSession(sessionId, accountId)) {
new Thread(new Runnable() {
public void run() {
try {
if (examNotificationQueue.hasItems()) {
ExamNotificationQueueItemModel examNotificationQueueItemModel = examNotificationQueue.dequeue();
if (examNotificationQueueItemModel.getAccountId() == accountId) {
LOGGER.info("[START] Check exam notification API");
LOGGER.info("Account ID: " + accountId);
LOGGER.info("Get notification with exam ID: " + examNotificationQueueItemModel.getExamName());
String result = gson.toJson(examNotificationQueueItemModel);
final OutboundEvent.Builder eventBuilder
= new OutboundEvent.Builder();
eventBuilder.data(result);
final OutboundEvent event = eventBuilder.build();
eventOutput.write(event);
LOGGER.info("[END]");
} else {
examNotificationQueue.enqueue(examNotificationQueueItemModel);
}
}
} catch (IOException e) {
throw new RuntimeException(
"Error when writing the event.", e);
} finally {
try {
eventOutput.close();
} catch (IOException ioClose) {
throw new RuntimeException(
"Error when closing the event output.", ioClose);
}
}
}
}).start();
}
return eventOutput;
}
Index.js
function checkExamNotification() {
var url = contextPath + '/api/notification/checkExamNotification?accountId=' + accountId + '&sessionId=' + sessionId;
var source = new EventSource(url);
source.onmessage = function (event) {
displayNumberOfNotification();
};
}