2013-05-19 4 views
3

Есть ли более читаемый способ очереди на ряд асинхронных эффектов, которые они выполняются синхронно?очереди синхронно с jquery

var element1 = $('#div1'); 
var element2 = $('#div2'); 

$(element2).hide(); 
$(element1).on('click',function(){ 
    $(element1).fadeOut(1000,function(){ 
     $(element2).fadeIn(1000, function(){ 
      $(element2).hide(); 
      alert('hello'); 
     }); 
    }); 
}); 
+3

Разве это не легко читаемым? –

+1

нет, если вы хотите поставить в очередь 20 эффектов подряд. – Zim84

+0

@ Zim84 Это причина моего вопроса. – Elisabeth

ответ

3

Вы можете предотвратить все более глубокий эффект гнездования, если используете систему на основе обещаний.

$.when(
    $(element1).fadeOut(1000) 
).then(function() { 
    return $(element2).fadeIn(1000); 
}).then(function() { 
    return $(element2).hide(); 
}).then(function() { 
    return $(element1).fadeIn(1000); 
}).then(function() { 
    return $(element1).fadeOut(1000); 
}); 

Демо: http://jsfiddle.net/tYhNq/1

Вы заметите, что делает его очень легко изменить порядок анимации.

«Трюк» является то, что $.when() method возвращает объект обещания, связанный с первой анимацией, так, то вы можете просто цепь кучи .then() вызовов, отметив, что каждый then() обратного вызова должен возвращать результат своей анимации.

Конечно, вы можете напрямую подключать анимации к одному элементу, например. .fadeIn(100).fadeOut(100)...

+0

Я бы предпочел $ .when в начале и удалить .promise как: $ .when ($ (element1) .fadeOut (1000)) и т. Д. Это более ясное, я думаю. – Elisabeth

+0

Вы правы. '$ .when()' является более аккуратным, как показано в [этой обновленной скрипке] (http://jsfiddle.net/tYhNq/1/). ('.promise()' был только первым способом, который пришел на ум.) – nnnnnn

+0

Можете ли вы, пожалуйста, изменить свое решение с помощью $ .when? то я отмечаю это как ответ :) только для остальных ... никто не должен читать комментарии ... – Elisabeth

1

Эта проблема называется «callback hell». В NodeJS у вас есть опция async, чтобы «убежать» от нее.

Я не нашел соответствующий вариант в jQuery.

Мое предложение создать одну функцию для каждого эффекта, как ниже:

var element1 = $('#div1'); 
var element2 = $('#div2'); 

$(element2).hide(); 

var finished = function() { console.log(":-)"); } 
var hide = function() { element2.hide(); finished(); } 
var fadeIn = function() { element2.fadeIn(1000, hide); } 
var clicked = function() { element1.fadeOut(1000, fadeIn); } 

$(element1).on('click', clicked); 

JSFIDDLE