Подтвердить что ты не робот

Выполнить функцию jquery после выполнения другой функции

Я хочу выполнить пользовательскую функцию jquery после завершения другой пользовательской функции Первая функция используется для создания эффекта "пишущей машинки"

function Typer()
{
     var srcText = 'EXAMPLE ';
    var i = 0;
    var result = srcText[i];
    setInterval(function() {
            if(i == srcText.length) {
                clearInterval(this);
                return;
            };
            i++;
            result += srcText[i].replace("\n", "<br />");
            $("#message").html( result);
    },
    100);

}

а вторая функция воспроизводит звук

function playBGM()
{
    document.getElementById('bgm').play();
}

Я вызываю функции один за другим, например

Typer();
playBGM();

Но звук начинает воспроизводиться по мере ввода текста. Я хочу воспроизвести звук только после того, как пишущая машинка закончилась.

Вот что я пробовал: http://jsfiddle.net/GkUEN/5/

Как я могу это исправить?

4b9b3361

Ответ 1

Вы должны использовать параметр обратного вызова:

function Typer(callback)
{
    var srcText = 'EXAMPLE ';
    var i = 0;
    var result = srcText[i];
    var interval = setInterval(function() {
        if(i == srcText.length - 1) {
            clearInterval(interval);
            callback();
            return;
        }
        i++;
        result += srcText[i].replace("\n", "<br />");
        $("#message").html(result);
    },
    100);
    return true;


}

function playBGM () {
    alert("Play BGM function");
    $('#bgm').get(0).play();
}

Typer(function () {
    playBGM();
});

// or one-liner: Typer(playBGM);

Итак, вы передаете функцию как параметр (callback), который будет вызываться в этом if до return.

Кроме того, это является хорошей статьей о обратных вызовах.

JSFIDDLE

Ответ 2

Вы можете использовать ниже код

$.when( Typer() ).done(function() {
       playBGM();
});

Ответ 3

Вы также можете использовать пользовательские события:

function Typer() {
    // Some stuff

    $(anyDomElement).trigger("myCustomEvent");
}


$(anyDomElement).on("myCustomEvent", function() {
    // Some other stuff
});

Ответ 4

Отложенные promises - отличный способ упорядочить выполнение функций аккуратно и легко. Независимо от того, работают ли AJAX или обычные функции, они обеспечивают большую гибкость, чем обратные вызовы, и мне стало легче понять.

function Typer()
{
var dfd = $.Deferred();
    var srcText = 'EXAMPLE ';
    var i = 0;
    var result = srcText[i];
    setInterval(function() {
            if(i == srcText.length) {
                clearInterval(this);
                dfd.resolve();
            };
            i++;
            result += srcText[i].replace("\n", "<br />");
            $("#message").html( result);
    },
    100);
  return dfd.promise();
}

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

function playBGM()
{
  var playsound = $.Deferred();
  $('#bgm')[0].play();
  $("#bgm").on("ended", function() {
     playsound.resolve();
  });
    return playsound.promise();
}


function thirdFunction() {
    alert('third function');
}

Теперь вызовите все это следующим образом: (обязательно используйте JQuery 1.9.1 или выше, поскольку я обнаружил, что 1.7.2 выполняет все функции сразу, а не ждет, чтобы каждый из них разрешил.)

Typer().then(playBGM).then(thirdFunction);  

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