У меня проблема с функциями обратного вызова в javascript. То, что я хочу сделать, это: loop on a for и вызов функции, передающей i
как параметр. Имея это в виду, мне нужно перейти к следующему взаимодействию только после того, как предыдущий закончен. Я не знаю, если это проблема, но внутри функции я представляемый i
в качестве параметра, у меня есть еще одна функции обратного вызова. Вот мой код:
for(i=0; i<10; i++) {
aux(i, function(success) {
/*
* this should be made interaction by interaction
* but what happens is: while I'm still running my first interaction
* (i=0), the code loops for i=1, i=2, etc. before the response of
* the previous interaction
*/
if(!success)
doSomething();
else
doSomethingElse();
});
}
function aux(i, success) {
... //here I make my logic with "i" sent as parameter
getReturnFromAjax(function(response) {
if(response)
return success(true);
else
return success(false);
});
});
function getReturnFromAjax(callback) {
...
$.ajax({
url: myUrl,
type: "POST",
success: function (response) {
return callback(response);
}
});
}
jQuery Deferred
могут быть немного сложными, чтобы получить право. То, что вам нужно сделать, это укладывать свои обещания в цепочку. Например:
var
// create a deferred object
dfd = $.Deferred(),
// get the promise
promise = dfd.promise(),
// the loop variable
i
;
for(i = 0; i < 10; i += 1) {
// use 'then' and use the new promise for next itteration
promise = promise.then(
// prepare the function to be called, but don't execute it!
// (see docs for .bind)
aux.bind(null, i, function(success) {
success ? doSomethingElse() : doSomething();
})
);
}
// resolve the deferred object
dfd.resolve();
для того, чтобы это работало, aux
также должен вернуть обещание, но $.ajax
уже делает это, поэтому просто передайте его, и все должно работать:
в aux
:
function aux(i, callback) {
console.log('executing for 'aux' with', i);
// return the ajax-promise
return getReturnFromAjax(function(response) {
callback(Boolean(response));
});
}
в getReturnFromAjax
:
function getReturnFromAjax(callback) {
// return the ajax-promise
return $.ajax({
url: '%your-url%',
type: '%method%',
success: function (response) {
callback(response);
}
});
}
Я бы предположил, что вы заглянули в jQuery Deferred Objects и jQuery.Deferred() -method вместо того, чтобы создавать собственные функции очереди обратного вызова (так как вы уже используете jQuery).
Описание: Функция-конструктор, которая возвращает цельный объект утилиты с методами регистрации нескольких обратных вызовов в очереди обратного вызова, вызывает очереди обратного вызова и ретранслирует состояние успеха или отказа любой синхронной или асинхронной функции.
У меня нет опыта работы с jQuery, но ваш обратный вызов выглядит немного подозрительным для меня.
В простой JS я предлагаю попробовать что-то среди строк этого:
function yourMainFunction
{
function callbackHandler(result)
{
// Code that depends on on the result of the callback
}
getAjaxResults(callbackHandler);
}
function getAjaxResults(callbackHandler)
{
// Create xmlHttpRequest Handler, etc.
// Make your AJAX request
xmlHttp.onreadystatechange = function()
{
if (xmlHttp.readyState == 4 && xmlHttp.status==200)
{
// Do stuff you want to do if the request was successful
// Define a variable with the value(s) you want to return to the main function
callbackHandler(yourReturnVariable);
}
}
}