для цикла функция с отложенным

У меня есть простая функция для отображения консольного сообщения с именем элемента. Что-то простое, например:

for(var i =0; i< array.length; i++)
child(array[i]);

var child = function(itemname){
console.log(itemname);
}

Здесь длина массива является динамической, как и содержащиеся в нем значения. Теперь я хочу добавить некоторую анимацию внутри дочерней функции и определенно хочу, чтобы она закончилась первой, прежде чем она снова будет вызвана циклом for.

Я знаю, как использовать jQuery Deferred и могу вызывать одну функцию после завершения другой, но здесь я не знаю, как вызвать ее использование внутри цикла for. Я не уверен, что это правильный вариант для использования здесь. Итак, что я хочу сделать, так это,

for(var i =0; i< array.length; i++) //for example 3 times
{

child(i) //call child and pass the the value of i
wait till child function completes

}

Таким образом, с каждым приращением i будет вызываться дочерняя функция, и цикл for должен ждать, пока дочерняя функция не будет завершена, а затем снова вызывать дочернюю функцию .... до тех пор, пока условие не будет выполнено.

Я нашел несколько решений с функциональностью $.when.apply, но не мог понять, как ее использовать. Любая документация, образец, справочник, статья "для чтения" поможет!

РЕДАКТИРОВАТЬ: Думаю, мне не стоило использовать пример с анимацией. моя вина. Предположим, что дочерняя функция делает вызов ajax. Теперь я хочу вызвать дочернюю функцию i раз и хочу, чтобы цикл каждый раз ждал завершения вызова ajax, прежде чем вызывать его снова. Это одна и та же функция, которую я хочу вызывать более одного раза. нет цепочки.


person sandiejat    schedule 22.10.2014    source источник
comment
Разве он уже не ждет завершения? Я имею в виду, насколько я знаю, выполнение вашего кода должно быть линейным. Операторы as in будут выполняться по порядку, и каждый оператор будет ждать, пока не будет выполнен предыдущий.   -  person Zero    schedule 22.10.2014
comment
Я думаю, что нет, так как jQuery сделает асинхронный вызов дочерней функции, и тогда цикл for не будет ждать, пока завершится анимация внутри дочерней функции. Предположим, что у вас есть вызов AJAX внутри дочерней функции, и вы хотите вызвать эту дочернюю функцию 10 раз и хотите, чтобы цикл for каждый раз ждал завершения вызова, а затем снова вызывал дочернюю функцию. Я имею смысл?   -  person sandiejat    schedule 22.10.2014


Ответы (2)


Здесь вам не нужен цикл for, это не совсем правильный инструмент для цепных анимаций. Вместо этого вы можете использовать встроенный объект jQuery.Deferred. Ниже приведен пример того, как вы можете его использовать. Как видите, вам нужно сделать так, чтобы ваша функция анимации child возвращала отложенный объект. После этого вы можете использовать его метод then, чтобы решить, нужно ли вам вызывать child еще раз, пока array не будет содержать элементы.

var array = ['message one', 'and another', 'finally one more'];

// Invoke child until array has elements, no loops are needed here
child(array.shift()).then(function next() {
    if (array.length) {
        child(array.shift()).then(next);
    }
});


// An example of child function.
// Important part here is that this function returns deferred promise
// which is resolved once animation is complete.
function child(i) {
    var $message = $('<div class="message">' + i + '</div>');
    $message.appendTo('body');
    return $.Deferred(function() {
        $message.delay(1000).fadeOut(1000, this.resolve);
    });
}
.message {
    padding: 20px;
    background: #55E755;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

UPD. Если у вас есть вызов AJAX в дочерней функции, это еще проще. Вы просто возвращаете что-то вроде этого $.get(...), это уже промис, не нужно создавать новый с $.Deferred.

person dfsq    schedule 22.10.2014
comment
Большое спасибо за логику! - person sandiejat; 22.10.2014

Как насчет того, чтобы сделать это рекурсивно?

function child(i){
    if(i<array.length){
        console.log(array[i]);
        child(i+1);
    }
}

var array = ['1','2','3'];

child(0);
person roullie    schedule 22.10.2014