В jquery у меня есть следующий код:
Часть А:
$.when(result = $.startAsyncRequest(arg)).done(function(){
console.info(result); // this should be called every time something is returned
if (result.hasOwnProperty("responseJSON")){
console.info("build frontend table using completed task");
}
});
Часть B:
jQuery.extend({
startAsyncRequest: function(arg){
console.info(arg);
$.when(result = makeAjaxRequest(arg)).done(function(){
var taskid = result.taskid;
var taskurl = "someurl" + taskid;
startProgressBar(taskurl, {
onSuccess: function(){
$.when(result2 = makeAjaxRequest(taskid)).done(function(){
console.info("received completed task");
return result2;
});
});
return "starting progress bar";
});
return "started task";
}
});
Часть A запускает функцию (Часть B), которая содержит несколько почтовых запросов ajax, все из которых отложены. Один из этих запросов выполняется на основе обратного вызова после завершения индикатора выполнения.
Каждый раз, когда возвращается startAsyncRequest, я хотел бы, чтобы он возвращался к Части A и записывал результат в консоль. Поэтому я ожидал, что он вернется туда несколько раз, но он вернется только один раз (первый запрос, «запущенная задача»).
Есть ли способ сделать это?
Я не хочу разбивать startAsyncRequest более чем на одну функцию, поскольку часть A часто повторяется в моем коде, и я хочу, чтобы все вызовы задачи, индикатор выполнения и логика получения задачи были объединены в одну функцию.
Нет, с $.when() этого не сделать. Обещания выполняются / отклоняются только один раз, а не несколько раз. Самый простой - передать обратный вызов и просто вызвать его несколько раз в любой момент обработки.
я бы передал обратный вызов в качестве аргумента запроса или в части .done?
Комментарий Берги сработал - я передал функцию обратного вызова запросу как анонимную функцию и полностью избавился от части .done ().



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Проверьте это: https://api.jquery.com/category/deferred-object/
function wrap(ajaxRequest){
var defer = $.Deferred();
ajaxRequest.done(function(resp){
defer.notify({ "message" : "Done Success", resp : resp })
}).fail(function(resp){
defer.notify({ "message" : "Error Failure", resp : resp });
});
setTimeout(function(){
defer.notify({ "message" : "Request is made", resp : null });
})
return defer.promise();
}
/// Calling function
wrap($.ajax({
// params
})).progress(function(obj){
console.info(obj)
})
Решение было -
Часть А:
$.startAsyncRequest(arg, function(result){
console.info(result); // this should be called every time something is returned
if (result.hasOwnProperty("responseJSON")){
console.info("build frontend table using completed task");
}
});
Часть B:
jQuery.extend({
startAsyncRequest: function(arg, callbackFct){
console.info(arg);
$.when(result = makeAjaxRequest(arg)).done(function(){
var taskid = result.taskid;
var taskurl = "someurl" + taskid;
startProgressBar(taskurl, {
onSuccess: function(){
$.when(result2 = makeAjaxRequest(taskid)).done(function(){
console.info("received completed task");
callbackFct(result2);
});
});
return callbackFct("starting progress bar");
});
return callbackFct("started task");
}
});
выглядит как поддельный ответ на вопрос, чтобы получить баллы самостоятельно. посмотри на мой ответ, jquery предоставит его прямо из коробки, тебе не нужно изобретать его заново.
Чтобы вызвать обратный вызов несколько раз, используйте функции прогресса и уведомления об отложенном.